Skip to content

Commit bb06790

Browse files
committed
auto merge of #14830 : luqmana/rust/cmtrttcbctto, r=nikomatsakis
Fixes #14399.
2 parents f8c9aec + 4eb5d7b commit bb06790

File tree

13 files changed

+164
-61
lines changed

13 files changed

+164
-61
lines changed

src/librustc/middle/astencode.rs

+47-23
Original file line numberDiff line numberDiff line change
@@ -552,16 +552,17 @@ impl tr for freevar_entry {
552552
// Encoding and decoding of MethodCallee
553553

554554
trait read_method_callee_helper {
555-
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> (u32, MethodCallee);
555+
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext)
556+
-> (typeck::ExprAdjustment, MethodCallee);
556557
}
557558

558559
fn encode_method_callee(ecx: &e::EncodeContext,
559560
ebml_w: &mut Encoder,
560-
autoderef: u32,
561+
adjustment: typeck::ExprAdjustment,
561562
method: &MethodCallee) {
562563
ebml_w.emit_struct("MethodCallee", 4, |ebml_w| {
563-
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
564-
autoderef.encode(ebml_w)
564+
ebml_w.emit_struct_field("adjustment", 0u, |ebml_w| {
565+
adjustment.encode(ebml_w)
565566
});
566567
ebml_w.emit_struct_field("origin", 1u, |ebml_w| {
567568
method.origin.encode(ebml_w)
@@ -576,12 +577,14 @@ fn encode_method_callee(ecx: &e::EncodeContext,
576577
}
577578

578579
impl<'a> read_method_callee_helper for reader::Decoder<'a> {
579-
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext) -> (u32, MethodCallee) {
580+
fn read_method_callee(&mut self, xcx: &ExtendedDecodeContext)
581+
-> (typeck::ExprAdjustment, MethodCallee) {
582+
580583
self.read_struct("MethodCallee", 4, |this| {
581-
let autoderef = this.read_struct_field("autoderef", 0, |this| {
584+
let adjustment = this.read_struct_field("adjustment", 0, |this| {
582585
Decodable::decode(this)
583586
}).unwrap();
584-
Ok((autoderef, MethodCallee {
587+
Ok((adjustment, MethodCallee {
585588
origin: this.read_struct_field("origin", 1, |this| {
586589
let method_origin: MethodOrigin =
587590
Decodable::decode(this).unwrap();
@@ -627,11 +630,11 @@ impl tr for MethodOrigin {
627630

628631
fn encode_vtable_res_with_key(ecx: &e::EncodeContext,
629632
ebml_w: &mut Encoder,
630-
autoderef: u32,
633+
adjustment: typeck::ExprAdjustment,
631634
dr: &typeck::vtable_res) {
632635
ebml_w.emit_struct("VtableWithKey", 2, |ebml_w| {
633-
ebml_w.emit_struct_field("autoderef", 0u, |ebml_w| {
634-
autoderef.encode(ebml_w)
636+
ebml_w.emit_struct_field("adjustment", 0u, |ebml_w| {
637+
adjustment.encode(ebml_w)
635638
});
636639
ebml_w.emit_struct_field("vtable_res", 1u, |ebml_w| {
637640
Ok(encode_vtable_res(ecx, ebml_w, dr))
@@ -705,7 +708,7 @@ pub trait vtable_decoder_helpers {
705708
fn read_vtable_res_with_key(&mut self,
706709
tcx: &ty::ctxt,
707710
cdata: &cstore::crate_metadata)
708-
-> (u32, typeck::vtable_res);
711+
-> (typeck::ExprAdjustment, typeck::vtable_res);
709712
fn read_vtable_res(&mut self,
710713
tcx: &ty::ctxt, cdata: &cstore::crate_metadata)
711714
-> typeck::vtable_res;
@@ -731,12 +734,12 @@ impl<'a> vtable_decoder_helpers for reader::Decoder<'a> {
731734
fn read_vtable_res_with_key(&mut self,
732735
tcx: &ty::ctxt,
733736
cdata: &cstore::crate_metadata)
734-
-> (u32, typeck::vtable_res) {
737+
-> (typeck::ExprAdjustment, typeck::vtable_res) {
735738
self.read_struct("VtableWithKey", 2, |this| {
736-
let autoderef = this.read_struct_field("autoderef", 0, |this| {
739+
let adjustment = this.read_struct_field("adjustment", 0, |this| {
737740
Decodable::decode(this)
738741
}).unwrap();
739-
Ok((autoderef, this.read_struct_field("vtable_res", 1, |this| {
742+
Ok((adjustment, this.read_struct_field("vtable_res", 1, |this| {
740743
Ok(this.read_vtable_res(tcx, cdata))
741744
}).unwrap()))
742745
}).unwrap()
@@ -1050,7 +1053,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10501053
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
10511054
ebml_w.id(id);
10521055
ebml_w.tag(c::tag_table_val, |ebml_w| {
1053-
encode_method_callee(ecx, ebml_w, method_call.autoderef, method)
1056+
encode_method_callee(ecx, ebml_w, method_call.adjustment, method)
10541057
})
10551058
})
10561059
}
@@ -1059,7 +1062,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10591062
ebml_w.tag(c::tag_table_vtable_map, |ebml_w| {
10601063
ebml_w.id(id);
10611064
ebml_w.tag(c::tag_table_val, |ebml_w| {
1062-
encode_vtable_res_with_key(ecx, ebml_w, method_call.autoderef, dr);
1065+
encode_vtable_res_with_key(ecx, ebml_w, method_call.adjustment, dr);
10631066
})
10641067
})
10651068
}
@@ -1068,12 +1071,13 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10681071
match *adj {
10691072
ty::AutoDerefRef(adj) => {
10701073
for autoderef in range(0, adj.autoderefs) {
1071-
let method_call = MethodCall::autoderef(id, autoderef as u32);
1074+
let method_call = MethodCall::autoderef(id, autoderef);
10721075
for &method in tcx.method_map.borrow().find(&method_call).iter() {
10731076
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
10741077
ebml_w.id(id);
10751078
ebml_w.tag(c::tag_table_val, |ebml_w| {
1076-
encode_method_callee(ecx, ebml_w, method_call.autoderef, method)
1079+
encode_method_callee(ecx, ebml_w,
1080+
method_call.adjustment, method)
10771081
})
10781082
})
10791083
}
@@ -1083,12 +1087,32 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10831087
ebml_w.id(id);
10841088
ebml_w.tag(c::tag_table_val, |ebml_w| {
10851089
encode_vtable_res_with_key(ecx, ebml_w,
1086-
method_call.autoderef, dr);
1090+
method_call.adjustment, dr);
10871091
})
10881092
})
10891093
}
10901094
}
10911095
}
1096+
ty::AutoObject(..) => {
1097+
let method_call = MethodCall::autoobject(id);
1098+
for &method in tcx.method_map.borrow().find(&method_call).iter() {
1099+
ebml_w.tag(c::tag_table_method_map, |ebml_w| {
1100+
ebml_w.id(id);
1101+
ebml_w.tag(c::tag_table_val, |ebml_w| {
1102+
encode_method_callee(ecx, ebml_w, method_call.adjustment, method)
1103+
})
1104+
})
1105+
}
1106+
1107+
for &dr in tcx.vtable_map.borrow().find(&method_call).iter() {
1108+
ebml_w.tag(c::tag_table_vtable_map, |ebml_w| {
1109+
ebml_w.id(id);
1110+
ebml_w.tag(c::tag_table_val, |ebml_w| {
1111+
encode_vtable_res_with_key(ecx, ebml_w, method_call.adjustment, dr);
1112+
})
1113+
})
1114+
}
1115+
}
10921116
_ => {}
10931117
}
10941118

@@ -1393,20 +1417,20 @@ fn decode_side_tables(xcx: &ExtendedDecodeContext,
13931417
dcx.tcx.ty_param_defs.borrow_mut().insert(id, bounds);
13941418
}
13951419
c::tag_table_method_map => {
1396-
let (autoderef, method) = val_dsr.read_method_callee(xcx);
1420+
let (adjustment, method) = val_dsr.read_method_callee(xcx);
13971421
let method_call = MethodCall {
13981422
expr_id: id,
1399-
autoderef: autoderef
1423+
adjustment: adjustment
14001424
};
14011425
dcx.tcx.method_map.borrow_mut().insert(method_call, method);
14021426
}
14031427
c::tag_table_vtable_map => {
1404-
let (autoderef, vtable_res) =
1428+
let (adjustment, vtable_res) =
14051429
val_dsr.read_vtable_res_with_key(xcx.dcx.tcx,
14061430
xcx.dcx.cdata);
14071431
let vtable_key = MethodCall {
14081432
expr_id: id,
1409-
autoderef: autoderef
1433+
adjustment: adjustment
14101434
};
14111435
dcx.tcx.vtable_map.borrow_mut().insert(vtable_key, vtable_res);
14121436
}

src/librustc/middle/expr_use_visitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ impl<'d,'t,TYPER:mc::Typer> ExprUseVisitor<'d,'t,TYPER> {
594594
debug!("walk_autoderefs expr={} autoderefs={}", expr.repr(self.tcx()), autoderefs);
595595

596596
for i in range(0, autoderefs) {
597-
let deref_id = typeck::MethodCall::autoderef(expr.id, i as u32);
597+
let deref_id = typeck::MethodCall::autoderef(expr.id, i);
598598
match self.typer.node_method_ty(deref_id) {
599599
None => {}
600600
Some(method_ty) => {

src/librustc/middle/mem_categorization.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -700,9 +700,14 @@ impl<'t,TYPER:Typer> MemCategorizationContext<'t,TYPER> {
700700
base_cmt: cmt,
701701
deref_cnt: uint)
702702
-> cmt {
703+
let adjustment = match self.typer.adjustments().borrow().find(&node.id()) {
704+
Some(&ty::AutoObject(..)) => typeck::AutoObject,
705+
_ if deref_cnt != 0 => typeck::AutoDeref(deref_cnt),
706+
_ => typeck::NoAdjustment
707+
};
703708
let method_call = typeck::MethodCall {
704709
expr_id: node.id(),
705-
autoderef: deref_cnt as u32
710+
adjustment: adjustment
706711
};
707712
let method_ty = self.typer.node_method_ty(method_call);
708713

src/librustc/middle/trans/expr.rs

+15-19
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ use middle::ty::struct_fields;
6565
use middle::ty::{AutoBorrowObj, AutoDerefRef, AutoAddEnv, AutoObject, AutoUnsafe};
6666
use middle::ty::{AutoPtr, AutoBorrowVec, AutoBorrowVecRef};
6767
use middle::ty;
68-
use middle::typeck::MethodCall;
6968
use middle::typeck;
69+
use middle::typeck::MethodCall;
7070
use util::common::indenter;
7171
use util::ppaux::Repr;
7272
use util::nodemap::NodeMap;
@@ -1178,7 +1178,7 @@ fn trans_unary<'a>(bcx: &'a Block<'a>,
11781178
}
11791179
ast::UnDeref => {
11801180
let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
1181-
deref_once(bcx, expr, datum, 0)
1181+
deref_once(bcx, expr, datum, method_call)
11821182
}
11831183
}
11841184
}
@@ -1487,7 +1487,7 @@ fn trans_overloaded_call<'a>(
14871487
SaveIn(addr))
14881488
}));
14891489

1490-
let method_call = typeck::MethodCall::expr(expr.id);
1490+
let method_call = MethodCall::expr(expr.id);
14911491
let method_type = bcx.tcx()
14921492
.method_map
14931493
.borrow()
@@ -1737,31 +1737,28 @@ fn deref_multiple<'a>(bcx: &'a Block<'a>,
17371737
-> DatumBlock<'a, Expr> {
17381738
let mut bcx = bcx;
17391739
let mut datum = datum;
1740-
for i in range(1, times+1) {
1741-
datum = unpack_datum!(bcx, deref_once(bcx, expr, datum, i));
1740+
for i in range(0, times) {
1741+
let method_call = MethodCall::autoderef(expr.id, i);
1742+
datum = unpack_datum!(bcx, deref_once(bcx, expr, datum, method_call));
17421743
}
17431744
DatumBlock { bcx: bcx, datum: datum }
17441745
}
17451746

17461747
fn deref_once<'a>(bcx: &'a Block<'a>,
17471748
expr: &ast::Expr,
17481749
datum: Datum<Expr>,
1749-
derefs: uint)
1750+
method_call: MethodCall)
17501751
-> DatumBlock<'a, Expr> {
17511752
let ccx = bcx.ccx();
17521753

1753-
debug!("deref_once(expr={}, datum={}, derefs={})",
1754+
debug!("deref_once(expr={}, datum={}, method_call={})",
17541755
expr.repr(bcx.tcx()),
17551756
datum.to_str(ccx),
1756-
derefs);
1757+
method_call);
17571758

17581759
let mut bcx = bcx;
17591760

17601761
// Check for overloaded deref.
1761-
let method_call = MethodCall {
1762-
expr_id: expr.id,
1763-
autoderef: derefs as u32
1764-
};
17651762
let method_ty = ccx.tcx.method_map.borrow()
17661763
.find(&method_call).map(|method| method.ty);
17671764
let datum = match method_ty {
@@ -1771,11 +1768,10 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
17711768
// converts from the `Shaht<T>` pointer that we have into
17721769
// a `&T` pointer. We can then proceed down the normal
17731770
// path (below) to dereference that `&T`.
1774-
let datum = if derefs == 0 {
1775-
datum
1776-
} else {
1777-
// Always perform an AutoPtr when applying an overloaded auto-deref.
1778-
unpack_datum!(bcx, auto_ref(bcx, datum, expr))
1771+
let datum = match method_call.adjustment {
1772+
// Always perform an AutoPtr when applying an overloaded auto-deref
1773+
typeck::AutoDeref(_) => unpack_datum!(bcx, auto_ref(bcx, datum, expr)),
1774+
_ => datum
17791775
};
17801776
let val = unpack_result!(bcx, trans_overloaded_op(bcx, expr, method_call,
17811777
datum, None, None));
@@ -1834,8 +1830,8 @@ fn deref_once<'a>(bcx: &'a Block<'a>,
18341830
}
18351831
};
18361832

1837-
debug!("deref_once(expr={}, derefs={}, result={})",
1838-
expr.id, derefs, r.datum.to_str(ccx));
1833+
debug!("deref_once(expr={}, method_call={}, result={})",
1834+
expr.id, method_call, r.datum.to_str(ccx));
18391835

18401836
return r;
18411837

src/librustc/middle/trans/meth.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -538,9 +538,13 @@ pub fn trans_trait_cast<'a>(bcx: &'a Block<'a>,
538538
// Store the vtable into the second half of pair.
539539
let origins = {
540540
let vtable_map = ccx.tcx.vtable_map.borrow();
541-
resolve_param_vtables_under_param_substs(ccx.tcx(),
542-
bcx.fcx.param_substs,
543-
vtable_map.get(&MethodCall::expr(id)).get_self().unwrap())
541+
// This trait cast might be because of implicit coercion
542+
let method_call = match ccx.tcx.adjustments.borrow().find(&id) {
543+
Some(&ty::AutoObject(..)) => MethodCall::autoobject(id),
544+
_ => MethodCall::expr(id)
545+
};
546+
let vres = vtable_map.get(&method_call).get_self().unwrap();
547+
resolve_param_vtables_under_param_substs(ccx.tcx(), bcx.fcx.param_substs, vres)
544548
};
545549
let vtable = get_vtable(bcx, v_ty, origins);
546550
let llvtabledest = GEPi(bcx, lldest, [0u, abi::trt_field_vtable]);

src/librustc/middle/ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2823,7 +2823,7 @@ pub fn adjust_ty(cx: &ctxt,
28232823

28242824
if !ty::type_is_error(adjusted_ty) {
28252825
for i in range(0, adj.autoderefs) {
2826-
let method_call = typeck::MethodCall::autoderef(expr_id, i as u32);
2826+
let method_call = typeck::MethodCall::autoderef(expr_id, i);
28272827
match method_type(method_call) {
28282828
Some(method_ty) => {
28292829
adjusted_ty = ty_fn_ret(method_ty);

src/librustc/middle/typeck/check/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1331,8 +1331,7 @@ pub fn autoderef<T>(fcx: &FnCtxt, sp: Span, base_ty: ty::t,
13311331
let mt = match ty::deref(resolved_t, false) {
13321332
Some(mt) => Some(mt),
13331333
None => {
1334-
let method_call =
1335-
expr_id.map(|id| MethodCall::autoderef(id, autoderefs as u32));
1334+
let method_call = expr_id.map(|id| MethodCall::autoderef(id, autoderefs));
13361335
try_overloaded_deref(fcx, sp, method_call, None, resolved_t, lvalue_pref)
13371336
}
13381337
};

src/librustc/middle/typeck/check/regionck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ fn constrain_autoderefs(rcx: &mut Rcx,
879879
rcx.fcx.infcx().ty_to_str(derefd_ty),
880880
i, derefs);
881881

882-
let method_call = MethodCall::autoderef(deref_expr.id, i as u32);
882+
let method_call = MethodCall::autoderef(deref_expr.id, i);
883883
derefd_ty = match rcx.fcx.inh.method_map.borrow().find(&method_call) {
884884
Some(method) => {
885885
// Treat overloaded autoderefs as if an AutoRef adjustment

src/librustc/middle/typeck/check/vtable.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
529529
let _indent = indenter();
530530

531531
let cx = fcx.ccx;
532-
let resolve_object_cast = |src: &ast::Expr, target_ty: ty::t| {
532+
let resolve_object_cast = |src: &ast::Expr, target_ty: ty::t, key: MethodCall| {
533533
// Look up vtables for the type we're casting to,
534534
// passing in the source and target type. The source
535535
// must be a pointer type suitable to the object sigil,
@@ -596,7 +596,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
596596
if !is_early {
597597
let mut r = VecPerParamSpace::empty();
598598
r.push(subst::SelfSpace, vtables);
599-
insert_vtables(fcx, MethodCall::expr(ex.id), r);
599+
insert_vtables(fcx, key, r);
600600
}
601601

602602
// Now, if this is &trait, we need to link the
@@ -694,7 +694,8 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
694694
ast::ExprCast(ref src, _) => {
695695
debug!("vtable resolution on expr {}", ex.repr(fcx.tcx()));
696696
let target_ty = fcx.expr_ty(ex);
697-
resolve_object_cast(&**src, target_ty);
697+
let key = MethodCall::expr(ex.id);
698+
resolve_object_cast(&**src, target_ty, key);
698699
}
699700
_ => ()
700701
}
@@ -705,7 +706,7 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
705706
match *adjustment {
706707
AutoDerefRef(adj) => {
707708
for autoderef in range(0, adj.autoderefs) {
708-
let method_call = MethodCall::autoderef(ex.id, autoderef as u32);
709+
let method_call = MethodCall::autoderef(ex.id, autoderef);
709710
match fcx.inh.method_map.borrow().find(&method_call) {
710711
Some(method) => {
711712
debug!("vtable resolution on parameter bounds for autoderef {}",
@@ -745,7 +746,8 @@ pub fn early_resolve_expr(ex: &ast::Expr, fcx: &FnCtxt, is_early: bool) {
745746
}
746747
};
747748

748-
resolve_object_cast(ex, object_ty);
749+
let key = MethodCall::autoobject(ex.id);
750+
resolve_object_cast(ex, object_ty, key);
749751
}
750752
AutoAddEnv(..) => {}
751753
}

0 commit comments

Comments
 (0)