Skip to content

librustc: WIP patch for upgrading the way rvalues are treated. #16009

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/libcore/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2006,7 +2006,8 @@ impl<A: Add<A, A> + PartialOrd + Clone + ToPrimitive> Iterator<A> for Range<A> {
// This first checks if the elements are representable as i64. If they aren't, try u64 (to
// handle cases like range(huge, huger)). We don't use uint/int because the difference of
// the i64/u64 might lie within their range.
let bound = match self.state.to_i64() {
let state = self.state.to_i64();
let bound = match state {
Some(a) => {
let sz = self.stop.to_i64().map(|b| b.checked_sub(&a));
match sz {
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -840,8 +840,10 @@ fn encode_inlined_item(ecx: &EncodeContext,
ebml_w: &mut Encoder,
ii: InlinedItemRef) {
let mut eii = ecx.encode_inlined_item.borrow_mut();
let eii: &mut EncodeInlinedItem = &mut *eii;
(*eii)(ecx, ebml_w, ii)
unsafe {
let eii: &mut EncodeInlinedItem = ::std::mem::transmute_copy(& &mut *eii);
(*eii)(ecx, ebml_w, ii)
}
}

fn style_fn_family(s: FnStyle) -> char {
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ impl<'a> CheckLoanCtxt<'a> {
let mut loan_path = loan_path;
loop {
match *loan_path {
LpVar(_) | LpUpvar(_) => {
LpVar(_) | LpUpvar(_) | LpAliasableRvalue(_) => {
break;
}
LpExtend(ref lp_base, _, _) => {
Expand Down Expand Up @@ -633,7 +633,7 @@ impl<'a> CheckLoanCtxt<'a> {
*/

match **lp {
LpVar(_) | LpUpvar(_) => {
LpVar(_) | LpUpvar(_) | LpAliasableRvalue(_) => {
// assigning to `x` does not require that `x` is initialized
}
LpExtend(ref lp_base, _, LpInterior(_)) => {
Expand Down Expand Up @@ -722,7 +722,9 @@ impl<'a> CheckLoanCtxt<'a> {
debug!("mark_writes_through_upvars_as_used_mut(cmt={})",
cmt.repr(this.tcx()));
match cmt.cat.clone() {
mc::cat_local(id) | mc::cat_arg(id) => {
mc::cat_local(id) |
mc::cat_arg(id) |
mc::cat_aliasable_rvalue(id) => {
this.tcx().used_mut_nodes.borrow_mut().insert(id);
return;
}
Expand Down
3 changes: 2 additions & 1 deletion src/librustc/middle/borrowck/gather_loans/gather_moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ fn check_and_get_illegal_move_origin(bccx: &BorrowckCtxt,

mc::cat_rvalue(..) |
mc::cat_local(..) |
mc::cat_arg(..) => {
mc::cat_arg(..) |
mc::cat_aliasable_rvalue(..) => {
None
}

Expand Down
8 changes: 8 additions & 0 deletions src/librustc/middle/borrowck/gather_loans/lifetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use middle::borrowck::*;
use euv = middle::expr_use_visitor;
use mc = middle::mem_categorization;
use middle::mem_categorization::Typer;
use middle::ty;
use util::ppaux::Repr;
use syntax::ast;
Expand Down Expand Up @@ -67,6 +68,7 @@ impl<'a> GuaranteeLifetimeContext<'a> {

match cmt.cat {
mc::cat_rvalue(..) |
mc::cat_aliasable_rvalue(..) |
mc::cat_copied_upvar(..) | // L-Local
mc::cat_local(..) | // L-Local
mc::cat_arg(..) | // L-Local
Expand Down Expand Up @@ -178,6 +180,12 @@ impl<'a> GuaranteeLifetimeContext<'a> {
mc::cat_arg(local_id) => {
ty::ReScope(self.bccx.tcx.region_maps.var_scope(local_id))
}
mc::cat_aliasable_rvalue(expr_id) => {
match self.bccx.tcx.temporary_scope(expr_id) {
Some(scope) => ty::ReScope(scope),
None => ty::ReStatic,
}
}
mc::cat_deref(_, _, mc::UnsafePtr(..)) => {
ty::ReStatic
}
Expand Down
28 changes: 18 additions & 10 deletions src/librustc/middle/borrowck/gather_loans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -395,9 +395,10 @@ impl<'a> GatherLoanCtxt<'a> {
//! from a local variable, mark the mutability decl as necessary.

match *loan_path {
LpVar(local_id) |
LpUpvar(ty::UpvarId{ var_id: local_id, closure_expr_id: _ }) => {
self.tcx().used_mut_nodes.borrow_mut().insert(local_id);
LpVar(id) |
LpUpvar(ty::UpvarId{ var_id: id, closure_expr_id: _ }) |
LpAliasableRvalue(id) => {
self.tcx().used_mut_nodes.borrow_mut().insert(id);
}
LpExtend(ref base, mc::McInherited, _) => {
self.mark_loan_path_as_mutated(&**base);
Expand Down Expand Up @@ -446,13 +447,20 @@ impl<'a> GatherLoanCtxt<'a> {
//! with immutable `&` pointers, because borrows of such pointers
//! do not require restrictions and hence do not cause a loan.

let lexical_scope = lp.kill_scope(self.bccx.tcx);
let rm = &self.bccx.tcx.region_maps;
if rm.is_subscope_of(lexical_scope, loan_scope) {
lexical_scope
} else {
assert!(self.bccx.tcx.region_maps.is_subscope_of(loan_scope, lexical_scope));
loan_scope
match lp.kill_scope(self.bccx.tcx) {
Some(lexical_scope) => {
let rm = &self.bccx.tcx.region_maps;
if rm.is_subscope_of(lexical_scope, loan_scope) {
lexical_scope
} else {
assert!(self.bccx
.tcx
.region_maps
.is_subscope_of(loan_scope, lexical_scope));
loan_scope
}
}
None => loan_scope,
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/librustc/middle/borrowck/gather_loans/restrictions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,12 @@ impl<'a> RestrictionsContext<'a> {
SafeIf(lp.clone(), vec!(lp))
}

mc::cat_aliasable_rvalue(expr_id) => {
// R-Variable, effectively
let lp = Rc::new(LpAliasableRvalue(expr_id));
SafeIf(lp.clone(), vec!(lp))
}

mc::cat_upvar(upvar_id, _) => {
// R-Variable, captured into closure
let lp = Rc::new(LpUpvar(upvar_id));
Expand Down
30 changes: 25 additions & 5 deletions src/librustc/middle/borrowck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ impl Loan {
pub enum LoanPath {
LpVar(ast::NodeId), // `x` in doc.rs
LpUpvar(ty::UpvarId), // `x` captured by-value into closure
LpAliasableRvalue(ast::NodeId), // potentially-aliasable rvalue
LpExtend(Rc<LoanPath>, mc::MutabilityCategory, LoanPathElem)
}

Expand All @@ -299,11 +300,15 @@ pub fn closure_to_block(closure_id: ast::NodeId,
}

impl LoanPath {
pub fn kill_scope(&self, tcx: &ty::ctxt) -> ast::NodeId {
pub fn kill_scope(&self, tcx: &ty::ctxt) -> Option<ast::NodeId> {
match *self {
LpVar(local_id) => tcx.region_maps.var_scope(local_id),
LpUpvar(upvar_id) =>
closure_to_block(upvar_id.closure_expr_id, tcx),
LpVar(local_id) => Some(tcx.region_maps.var_scope(local_id)),
LpUpvar(upvar_id) => {
Some(closure_to_block(upvar_id.closure_expr_id, tcx))
}
LpAliasableRvalue(expr_id) => {
tcx.region_maps.temporary_scope(expr_id)
}
LpExtend(ref base, _, _) => base.kill_scope(tcx),
}
}
Expand All @@ -328,6 +333,10 @@ pub fn opt_loan_path(cmt: &mc::cmt) -> Option<Rc<LoanPath>> {
Some(Rc::new(LpVar(id)))
}

mc::cat_aliasable_rvalue(id) => {
Some(Rc::new(LpAliasableRvalue(id)))
}

mc::cat_upvar(ty::UpvarId {var_id: id, closure_expr_id: proc_id}, _) |
mc::cat_copied_upvar(mc::CopiedUpvar { upvar_id: id,
onceness: _,
Expand Down Expand Up @@ -799,6 +808,10 @@ impl<'a> BorrowckCtxt<'a> {
out.push_str(ty::local_var_name_str(self.tcx, id).get());
}

LpAliasableRvalue(_) => {
out.push_str("<rvalue>")
}

LpExtend(ref lp_base, _, LpInterior(mc::InteriorField(fname))) => {
self.append_autoderefd_loan_path_to_string(&**lp_base, out);
match fname {
Expand Down Expand Up @@ -836,7 +849,10 @@ impl<'a> BorrowckCtxt<'a> {
self.append_autoderefd_loan_path_to_string(&**lp_base, out)
}

LpVar(..) | LpUpvar(..) | LpExtend(_, _, LpInterior(..)) => {
LpVar(..) |
LpUpvar(..) |
LpExtend(_, _, LpInterior(..)) |
LpAliasableRvalue(..) => {
self.append_loan_path_to_string(loan_path, out)
}
}
Expand Down Expand Up @@ -903,6 +919,10 @@ impl Repr for LoanPath {
format!("$({} captured by id={})", s, closure_expr_id)
}

&LpAliasableRvalue(id) => {
format!("$(rvalue{})", id)
}

&LpExtend(ref lp, _, LpDeref(_)) => {
format!("{}.*", lp.repr(tcx))
}
Expand Down
26 changes: 23 additions & 3 deletions src/librustc/middle/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use middle::dataflow::BitwiseOperator;
use middle::dataflow::DataFlowOperator;
use euv = middle::expr_use_visitor;
use mc = middle::mem_categorization;
use middle::mem_categorization::Typer;
use middle::ty;
use syntax::ast;
use syntax::ast_util;
Expand Down Expand Up @@ -163,7 +164,7 @@ pub type AssignDataFlow<'a> = DataFlowContext<'a, AssignDataFlowOperator>;

fn loan_path_is_precise(loan_path: &LoanPath) -> bool {
match *loan_path {
LpVar(_) | LpUpvar(_) => {
LpVar(_) | LpUpvar(_) | LpAliasableRvalue(_) => {
true
}
LpExtend(_, _, LpInterior(mc::InteriorElement(_))) => {
Expand Down Expand Up @@ -248,7 +249,7 @@ impl MoveData {
}

let index = match *lp {
LpVar(..) | LpUpvar(..) => {
LpVar(..) | LpUpvar(..) | LpAliasableRvalue(..) => {
let index = MovePathIndex(self.paths.borrow().len());

self.paths.borrow_mut().push(MovePath {
Expand Down Expand Up @@ -319,7 +320,7 @@ impl MoveData {
}
None => {
match **lp {
LpVar(..) | LpUpvar(..) => { }
LpVar(..) | LpUpvar(..) | LpAliasableRvalue(..) => { }
LpExtend(ref b, _, _) => {
self.add_existing_base_paths(b, result);
}
Expand Down Expand Up @@ -440,6 +441,17 @@ impl MoveData {
let path = *self.path_map.borrow().get(&path.loan_path);
self.kill_moves(path, kill_id, dfcx_moves);
}
LpAliasableRvalue(id) => {
match tcx.temporary_scope(id) {
Some(kill_id) => {
let path = *self.path_map
.borrow()
.get(&path.loan_path);
self.kill_moves(path, kill_id, dfcx_moves);
}
None => {}
}
}
LpExtend(..) => {}
}
}
Expand All @@ -456,6 +468,14 @@ impl MoveData {
let kill_id = closure_to_block(closure_expr_id, tcx);
dfcx_assign.add_kill(kill_id, assignment_index);
}
LpAliasableRvalue(expr_id) => {
match tcx.temporary_scope(expr_id) {
Some(kill_id) => {
dfcx_assign.add_kill(kill_id, assignment_index)
}
None => {}
}
}
LpExtend(..) => {
tcx.sess.bug("var assignment for non var path");
}
Expand Down
16 changes: 10 additions & 6 deletions src/librustc/middle/cfg/construct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,14 @@ impl<'a> CFGBuilder<'a> {

fn stmt(&mut self, stmt: Gc<ast::Stmt>, pred: CFGIndex) -> CFGIndex {
match stmt.node {
ast::StmtDecl(ref decl, _) => {
self.decl(&**decl, pred)
ast::StmtDecl(ref decl, stmt_id) => {
self.decl(&**decl, stmt_id, pred)
}

ast::StmtExpr(ref expr, _) | ast::StmtSemi(ref expr, _) => {
self.expr(expr.clone(), pred)
ast::StmtExpr(ref expr, stmt_id) |
ast::StmtSemi(ref expr, stmt_id) => {
let expr_exit = self.expr(expr.clone(), pred);
self.add_node(stmt_id, [expr_exit])
}

ast::StmtMac(..) => {
Expand All @@ -93,11 +95,13 @@ impl<'a> CFGBuilder<'a> {
}
}

fn decl(&mut self, decl: &ast::Decl, pred: CFGIndex) -> CFGIndex {
fn decl(&mut self, decl: &ast::Decl, stmt_id: ast::NodeId, pred: CFGIndex)
-> CFGIndex {
match decl.node {
ast::DeclLocal(ref local) => {
let init_exit = self.opt_expr(local.init.clone(), pred);
self.pat(&*local.pat, init_exit)
let stmt_exit = self.add_node(stmt_id, [init_exit]);
self.pat(&*local.pat, stmt_exit)
}

ast::DeclItem(_) => {
Expand Down
Loading