rustc: fix the fact that trans_lvalue rooted twice

This commit is contained in:
Niko Matsakis 2013-05-01 20:22:08 -04:00
parent 14bf5c4fe7
commit ef6b24d135
3 changed files with 29 additions and 55 deletions

View File

@ -966,7 +966,7 @@ pub fn root_pats_as_necessary(bcx: block,
let datum = Datum {val: val, ty: node_id_type(bcx, pat_id), let datum = Datum {val: val, ty: node_id_type(bcx, pat_id),
mode: ByRef, source: ZeroMem}; mode: ByRef, source: ZeroMem};
bcx = datum.root(bcx, br.pats[col].span, root_info); bcx = datum.root(bcx, br.pats[col].span, key, root_info);
// If we kept going, we'd only re-root the same value, so // If we kept going, we'd only re-root the same value, so
// return now. // return now.
return bcx; return bcx;

View File

@ -517,7 +517,8 @@ pub impl Datum {
} }
} }
fn root(&self, mut bcx: block, span: span, root_info: RootInfo) -> block { fn root(&self, mut bcx: block, span: span,
root_key: root_map_key, root_info: RootInfo) -> block {
/*! /*!
* *
* In some cases, borrowck will decide that an @T/@[]/@str * In some cases, borrowck will decide that an @T/@[]/@str
@ -525,8 +526,8 @@ pub impl Datum {
* case, we will call this function, which will stash a copy * case, we will call this function, which will stash a copy
* away until we exit the scope `scope_id`. */ * away until we exit the scope `scope_id`. */
debug!("root(root_info=%?, self=%?)", debug!("root(root_map_key=%?, root_info=%?, self=%?)",
root_info, self.to_str(bcx.ccx())); root_key, root_info, self.to_str(bcx.ccx()));
if bcx.sess().trace() { if bcx.sess().trace() {
trans_trace( trans_trace(
@ -674,7 +675,7 @@ pub impl Datum {
let key = root_map_key { id: expr_id, derefs: derefs }; let key = root_map_key { id: expr_id, derefs: derefs };
let bcx = match ccx.maps.root_map.find(&key) { let bcx = match ccx.maps.root_map.find(&key) {
None => bcx, None => bcx,
Some(&root_info) => self.root(bcx, span, root_info) Some(&root_info) => self.root(bcx, span, key, root_info)
}; };
// Perform the write guard, if necessary. // Perform the write guard, if necessary.

View File

@ -821,57 +821,30 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr))); trace_span!(bcx, expr.span, @shorten(bcx.expr_to_str(expr)));
let unrooted_datum = unpack_datum!(bcx, unrooted(bcx, expr)); return match expr.node {
ast::expr_paren(e) => {
// If the lvalue must remain rooted, create a scratch datum, copy unrooted(bcx, e)
// the lvalue in there, and then arrange for it to be cleaned up
// at the end of the scope with id `scope_id`:
let root_key = root_map_key { id: expr.id, derefs: 0u };
for bcx.ccx().maps.root_map.find(&root_key).each |&root_info| {
bcx = unrooted_datum.root(bcx, expr.span, *root_info);
}
return DatumBlock {bcx: bcx, datum: unrooted_datum};
fn unrooted(bcx: block, expr: @ast::expr) -> DatumBlock {
/*!
*
* Translates `expr`. Note that this version generally
* yields an unrooted, unmoved version. Rooting and possible
* moves are dealt with above in trans_lvalue_unadjusted().
*
* One exception is if `expr` refers to a local variable,
* in which case the source may already be FromMovedLvalue
* if appropriate.
*/
let mut bcx = bcx;
match expr.node {
ast::expr_paren(e) => {
return unrooted(bcx, e);
}
ast::expr_path(_) => {
return trans_def_lvalue(bcx, expr, bcx.def(expr.id));
}
ast::expr_field(base, ident, _) => {
return trans_rec_field(bcx, base, ident);
}
ast::expr_index(base, idx) => {
return trans_index(bcx, expr, base, idx);
}
ast::expr_unary(ast::deref, base) => {
let basedatum = unpack_datum!(bcx, trans_to_datum(bcx, base));
return basedatum.deref(bcx, base, 0);
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,
fmt!("trans_lvalue reached fall-through case: %?",
expr.node));
}
} }
} ast::expr_path(_) => {
trans_def_lvalue(bcx, expr, bcx.def(expr.id))
}
ast::expr_field(base, ident, _) => {
trans_rec_field(bcx, base, ident)
}
ast::expr_index(base, idx) => {
trans_index(bcx, expr, base, idx)
}
ast::expr_unary(ast::deref, base) => {
let basedatum = unpack_datum!(bcx, trans_to_datum(bcx, base));
basedatum.deref(bcx, base, 0)
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,
fmt!("trans_lvalue reached fall-through case: %?",
expr.node));
}
};
fn trans_rec_field(bcx: block, fn trans_rec_field(bcx: block,
base: @ast::expr, base: @ast::expr,