Skip to content

Commit d42e758

Browse files
committed
librustc: Don't translate an expr twice when implicitly coercing to a trait object. Fixes #11197.
1 parent 17f984c commit d42e758

File tree

3 files changed

+21
-22
lines changed

3 files changed

+21
-22
lines changed

src/librustc/middle/trans/expr.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -229,19 +229,12 @@ pub fn trans_to_datum<'a>(bcx: &'a Block<'a>, expr: &ast::Expr)
229229
}
230230
};
231231
}
232-
AutoObject(ref sigil, ref region, _, _, _, _) => {
232+
AutoObject(..) => {
233233

234234
let adjusted_ty = ty::expr_ty_adjusted(bcx.tcx(), expr);
235235
let scratch = scratch_datum(bcx, adjusted_ty, "__adjust", false);
236236

237-
let trait_store = match *sigil {
238-
ast::BorrowedSigil => ty::RegionTraitStore(region.expect("expected valid region")),
239-
ast::OwnedSigil => ty::UniqTraitStore,
240-
ast::ManagedSigil => ty::BoxTraitStore
241-
};
242-
243-
bcx = meth::trans_trait_cast(bcx, expr, expr.id, SaveIn(scratch.val),
244-
trait_store, false /* no adjustments */);
237+
bcx = meth::trans_trait_cast(bcx, expr, expr.id, SaveIn(scratch.val), Some(datum));
245238

246239
datum = scratch.to_appropriate_datum(bcx);
247240
datum.add_clean(bcx);
@@ -834,9 +827,9 @@ fn trans_rvalue_dps_unadjusted<'a>(
834827
}
835828
ast::ExprCast(val, _) => {
836829
match ty::get(node_id_type(bcx, expr.id)).sty {
837-
ty::ty_trait(_, _, store, _, _) => {
830+
ty::ty_trait(..) => {
838831
return meth::trans_trait_cast(bcx, val, expr.id,
839-
dest, store, true /* adjustments */);
832+
dest, None);
840833
}
841834
_ => {
842835
bcx.tcx().sess.span_bug(expr.span,

src/librustc/middle/trans/meth.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -637,22 +637,14 @@ pub fn trans_trait_cast<'a>(
637637
val: &ast::Expr,
638638
id: ast::NodeId,
639639
dest: expr::Dest,
640-
_store: ty::TraitStore,
641-
do_adjustments: bool)
640+
obj: Option<Datum>)
642641
-> &'a Block<'a> {
643642
let mut bcx = bcx;
644643
let _icx = push_ctxt("impl::trans_cast");
645644

646-
// Pick the right trans function
647-
let trans_into = if do_adjustments {
648-
expr::trans_into
649-
} else {
650-
expr::trans_into_unadjusted
651-
};
652-
653645
let lldest = match dest {
654646
Ignore => {
655-
return trans_into(bcx, val, Ignore);
647+
return expr::trans_into(bcx, val, Ignore);
656648
}
657649
SaveIn(dest) => dest
658650
};
@@ -667,7 +659,12 @@ pub fn trans_trait_cast<'a>(
667659
llboxdest = PointerCast(bcx,
668660
llboxdest,
669661
type_of(bcx.ccx(), v_ty).ptr_to());
670-
bcx = trans_into(bcx, val, SaveIn(llboxdest));
662+
bcx = match obj {
663+
Some(datum) => {
664+
datum.store_to_dest(bcx, SaveIn(llboxdest))
665+
}
666+
None => expr::trans_into(bcx, val, SaveIn(llboxdest))
667+
};
671668

672669
// Store the vtable into the pair or triple.
673670
// This is structured a bit funny because of dynamic borrow failures.

src/test/run-pass/trait-coercion.rs

+9
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
#[feature(managed_boxes)];
1212

13+
use std::io;
14+
1315
trait Trait {
1416
fn f(&self);
1517
}
@@ -29,6 +31,10 @@ fn f(x: @Trait) {
2931
x.f();
3032
}
3133

34+
fn foo(mut a: ~Writer) {
35+
a.write(bytes!("Hello\n"));
36+
}
37+
3238
pub fn main() {
3339
let a = Struct { x: 1, y: 2 };
3440
let b: @Trait = @a;
@@ -38,5 +44,8 @@ pub fn main() {
3844
let d: &Trait = &a;
3945
d.f();
4046
f(@a);
47+
48+
let out = io::stdout();
49+
foo(~out);
4150
}
4251

0 commit comments

Comments
 (0)