librustc: Don't translate an expr twice when implicitly coercing to a trait object. Fixes #11197.

This commit is contained in:
Luqman Aden 2014-01-13 20:34:23 -05:00
parent 17f984c54b
commit d42e75883b
3 changed files with 21 additions and 22 deletions

View File

@ -229,19 +229,12 @@ pub fn trans_to_datum<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
}
};
}
AutoObject(ref sigil, ref region, _, _, _, _) => {
AutoObject(..) => {
let adjusted_ty = ty::expr_ty_adjusted(bcx.tcx(), expr);
let scratch = scratch_datum(bcx, adjusted_ty, "__adjust", false);
let trait_store = match *sigil {
ast::BorrowedSigil => ty::RegionTraitStore(region.expect("expected valid region")),
ast::OwnedSigil => ty::UniqTraitStore,
ast::ManagedSigil => ty::BoxTraitStore
};
bcx = meth::trans_trait_cast(bcx, expr, expr.id, SaveIn(scratch.val),
trait_store, false /* no adjustments */);
bcx = meth::trans_trait_cast(bcx, expr, expr.id, SaveIn(scratch.val), Some(datum));
datum = scratch.to_appropriate_datum(bcx);
datum.add_clean(bcx);
@ -834,9 +827,9 @@ fn trans_rvalue_dps_unadjusted<'a>(
}
ast::ExprCast(val, _) => {
match ty::get(node_id_type(bcx, expr.id)).sty {
ty::ty_trait(_, _, store, _, _) => {
ty::ty_trait(..) => {
return meth::trans_trait_cast(bcx, val, expr.id,
dest, store, true /* adjustments */);
dest, None);
}
_ => {
bcx.tcx().sess.span_bug(expr.span,

View File

@ -637,22 +637,14 @@ pub fn trans_trait_cast<'a>(
val: &ast::Expr,
id: ast::NodeId,
dest: expr::Dest,
_store: ty::TraitStore,
do_adjustments: bool)
obj: Option<Datum>)
-> &'a Block<'a> {
let mut bcx = bcx;
let _icx = push_ctxt("impl::trans_cast");
// Pick the right trans function
let trans_into = if do_adjustments {
expr::trans_into
} else {
expr::trans_into_unadjusted
};
let lldest = match dest {
Ignore => {
return trans_into(bcx, val, Ignore);
return expr::trans_into(bcx, val, Ignore);
}
SaveIn(dest) => dest
};
@ -667,7 +659,12 @@ pub fn trans_trait_cast<'a>(
llboxdest = PointerCast(bcx,
llboxdest,
type_of(bcx.ccx(), v_ty).ptr_to());
bcx = trans_into(bcx, val, SaveIn(llboxdest));
bcx = match obj {
Some(datum) => {
datum.store_to_dest(bcx, SaveIn(llboxdest))
}
None => expr::trans_into(bcx, val, SaveIn(llboxdest))
};
// Store the vtable into the pair or triple.
// This is structured a bit funny because of dynamic borrow failures.

View File

@ -10,6 +10,8 @@
#[feature(managed_boxes)];
use std::io;
trait Trait {
fn f(&self);
}
@ -29,6 +31,10 @@ fn f(x: @Trait) {
x.f();
}
fn foo(mut a: ~Writer) {
a.write(bytes!("Hello\n"));
}
pub fn main() {
let a = Struct { x: 1, y: 2 };
let b: @Trait = @a;
@ -38,5 +44,8 @@ pub fn main() {
let d: &Trait = &a;
d.f();
f(@a);
let out = io::stdout();
foo(~out);
}