mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
librustc: Don't translate an expr twice when implicitly coercing to a trait object. Fixes #11197.
This commit is contained in:
parent
17f984c54b
commit
d42e75883b
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user