Skip to content

Commit 42e545f

Browse files
committed
Auto merge of #26694 - eddyb:method-nan, r=arielb1
`MethodCallee` now has no information about the method, other than its `DefId`. The previous bits of information can be recovered as follows: ```rust let method_item = tcx.impl_or_trait_item(callee.def_id); let container = method_item.container(); ``` The method is inherent if `container` is a `ty::ImplContainer`: * the `impl` the method comes from is `container.id()` The method is a trait method if `container` is a `ty::TraitContainer: * the `trait` the method is part of is `container.id()` * a `ty::TraitRef` can be constructed by putting together: * `container.id()` as the `trait` ID * `callee.substs.clone().method_to_trait()` as the `trait` substs (including `Self`) * the above `trait_ref` is a valid `T: Trait<A, B, C>` predicate * selecting `trait_ref` could result in one of the following: * `traits::VtableImpl(data)`: static dispatch to `data.impl_def_id` * `traits::VtableObject(data)`: dynamic dispatch, with the vtable index: `traits::get_vtable_index_of_object_method(tcx, data, callee.def_id)` * other variants of `traits::Vtable`: various other `impl` sources
2 parents b381449 + d256eb1 commit 42e545f

33 files changed

+591
-1178
lines changed

src/librustc/middle/astencode.rs

+15-170
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use middle::check_const::ConstQualif;
2929
use middle::privacy::{AllPublic, LastMod};
3030
use middle::subst;
3131
use middle::subst::VecPerParamSpace;
32-
use middle::ty::{self, Ty, MethodCall, MethodCallee, MethodOrigin};
32+
use middle::ty::{self, Ty};
3333

3434
use syntax::{ast, ast_util, codemap, fold};
3535
use syntax::codemap::Span;
@@ -600,21 +600,21 @@ impl tr for ty::UpvarCapture {
600600

601601
trait read_method_callee_helper<'tcx> {
602602
fn read_method_callee<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
603-
-> (u32, MethodCallee<'tcx>);
603+
-> (u32, ty::MethodCallee<'tcx>);
604604
}
605605

606606
fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
607607
rbml_w: &mut Encoder,
608608
autoderef: u32,
609-
method: &MethodCallee<'tcx>) {
609+
method: &ty::MethodCallee<'tcx>) {
610610
use serialize::Encoder;
611611

612612
rbml_w.emit_struct("MethodCallee", 4, |rbml_w| {
613613
rbml_w.emit_struct_field("autoderef", 0, |rbml_w| {
614614
autoderef.encode(rbml_w)
615615
});
616-
rbml_w.emit_struct_field("origin", 1, |rbml_w| {
617-
Ok(rbml_w.emit_method_origin(ecx, &method.origin))
616+
rbml_w.emit_struct_field("def_id", 1, |rbml_w| {
617+
Ok(rbml_w.emit_def_id(method.def_id))
618618
});
619619
rbml_w.emit_struct_field("ty", 2, |rbml_w| {
620620
Ok(rbml_w.emit_ty(ecx, method.ty))
@@ -627,21 +627,20 @@ fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
627627

628628
impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
629629
fn read_method_callee<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
630-
-> (u32, MethodCallee<'tcx>) {
630+
-> (u32, ty::MethodCallee<'tcx>) {
631631

632632
self.read_struct("MethodCallee", 4, |this| {
633-
let autoderef = this.read_struct_field("autoderef", 0, |this| {
634-
Decodable::decode(this)
635-
}).unwrap();
636-
Ok((autoderef, MethodCallee {
637-
origin: this.read_struct_field("origin", 1, |this| {
638-
Ok(this.read_method_origin(dcx))
633+
let autoderef = this.read_struct_field("autoderef", 0,
634+
Decodable::decode).unwrap();
635+
Ok((autoderef, ty::MethodCallee {
636+
def_id: this.read_struct_field("def_id", 1, |this| {
637+
Ok(this.read_def_id(dcx))
639638
}).unwrap(),
640639
ty: this.read_struct_field("ty", 2, |this| {
641640
Ok(this.read_ty(dcx))
642641
}).unwrap(),
643642
substs: this.read_struct_field("substs", 3, |this| {
644-
Ok(this.read_substs(dcx))
643+
Ok(dcx.tcx.mk_substs(this.read_substs(dcx)))
645644
}).unwrap()
646645
}))
647646
}).unwrap()
@@ -707,9 +706,6 @@ impl<'a, 'tcx> get_ty_str_ctxt<'tcx> for e::EncodeContext<'a, 'tcx> {
707706
trait rbml_writer_helpers<'tcx> {
708707
fn emit_closure_type<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
709708
closure_type: &ty::ClosureTy<'tcx>);
710-
fn emit_method_origin<'a>(&mut self,
711-
ecx: &e::EncodeContext<'a, 'tcx>,
712-
method_origin: &ty::MethodOrigin<'tcx>);
713709
fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
714710
fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
715711
fn emit_type_param_def<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
@@ -741,73 +737,6 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
741737
});
742738
}
743739

744-
fn emit_method_origin<'b>(&mut self,
745-
ecx: &e::EncodeContext<'b, 'tcx>,
746-
method_origin: &ty::MethodOrigin<'tcx>)
747-
{
748-
use serialize::Encoder;
749-
750-
self.emit_enum("MethodOrigin", |this| {
751-
match *method_origin {
752-
ty::MethodStatic(def_id) => {
753-
this.emit_enum_variant("MethodStatic", 0, 1, |this| {
754-
Ok(this.emit_def_id(def_id))
755-
})
756-
}
757-
758-
ty::MethodStaticClosure(def_id) => {
759-
this.emit_enum_variant("MethodStaticClosure", 1, 1, |this| {
760-
Ok(this.emit_def_id(def_id))
761-
})
762-
}
763-
764-
ty::MethodTypeParam(ref p) => {
765-
this.emit_enum_variant("MethodTypeParam", 2, 1, |this| {
766-
this.emit_struct("MethodParam", 2, |this| {
767-
try!(this.emit_struct_field("trait_ref", 0, |this| {
768-
Ok(this.emit_trait_ref(ecx, &p.trait_ref))
769-
}));
770-
try!(this.emit_struct_field("method_num", 0, |this| {
771-
this.emit_uint(p.method_num)
772-
}));
773-
try!(this.emit_struct_field("impl_def_id", 0, |this| {
774-
this.emit_option(|this| {
775-
match p.impl_def_id {
776-
None => this.emit_option_none(),
777-
Some(did) => this.emit_option_some(|this| {
778-
Ok(this.emit_def_id(did))
779-
})
780-
}
781-
})
782-
}));
783-
Ok(())
784-
})
785-
})
786-
}
787-
788-
ty::MethodTraitObject(ref o) => {
789-
this.emit_enum_variant("MethodTraitObject", 3, 1, |this| {
790-
this.emit_struct("MethodObject", 2, |this| {
791-
try!(this.emit_struct_field("trait_ref", 0, |this| {
792-
Ok(this.emit_trait_ref(ecx, &o.trait_ref))
793-
}));
794-
try!(this.emit_struct_field("object_trait_id", 0, |this| {
795-
Ok(this.emit_def_id(o.object_trait_id))
796-
}));
797-
try!(this.emit_struct_field("method_num", 0, |this| {
798-
this.emit_uint(o.method_num)
799-
}));
800-
try!(this.emit_struct_field("vtable_index", 0, |this| {
801-
this.emit_uint(o.vtable_index)
802-
}));
803-
Ok(())
804-
})
805-
})
806-
}
807-
}
808-
});
809-
}
810-
811740
fn emit_ty<'b>(&mut self, ecx: &e::EncodeContext<'b, 'tcx>, ty: Ty<'tcx>) {
812741
self.emit_opaque(|this| Ok(e::write_type(ecx, this, ty)));
813742
}
@@ -1077,7 +1006,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10771006
})
10781007
}
10791008

1080-
let method_call = MethodCall::expr(id);
1009+
let method_call = ty::MethodCall::expr(id);
10811010
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
10821011
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
10831012
rbml_w.id(id);
@@ -1089,7 +1018,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
10891018
match *adjustment {
10901019
ty::AdjustDerefRef(ref adj) => {
10911020
for autoderef in 0..adj.autoderefs {
1092-
let method_call = MethodCall::autoderef(id, autoderef as u32);
1021+
let method_call = ty::MethodCall::autoderef(id, autoderef as u32);
10931022
if let Some(method) = tcx.tables.borrow().method_map.get(&method_call) {
10941023
rbml_w.tag(c::tag_table_method_map, |rbml_w| {
10951024
rbml_w.id(id);
@@ -1150,8 +1079,6 @@ impl<'a> doc_decoder_helpers for rbml::Doc<'a> {
11501079
}
11511080

11521081
trait rbml_decoder_decoder_helpers<'tcx> {
1153-
fn read_method_origin<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
1154-
-> ty::MethodOrigin<'tcx>;
11551082
fn read_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Ty<'tcx>;
11561083
fn read_tys<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) -> Vec<Ty<'tcx>>;
11571084
fn read_trait_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
@@ -1235,88 +1162,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
12351162
}).unwrap()
12361163
}
12371164

1238-
fn read_method_origin<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
1239-
-> ty::MethodOrigin<'tcx>
1240-
{
1241-
self.read_enum("MethodOrigin", |this| {
1242-
let variants = &["MethodStatic", "MethodStaticClosure",
1243-
"MethodTypeParam", "MethodTraitObject"];
1244-
this.read_enum_variant(variants, |this, i| {
1245-
Ok(match i {
1246-
0 => {
1247-
let def_id = this.read_def_id(dcx);
1248-
ty::MethodStatic(def_id)
1249-
}
1250-
1251-
1 => {
1252-
let def_id = this.read_def_id(dcx);
1253-
ty::MethodStaticClosure(def_id)
1254-
}
1255-
1256-
2 => {
1257-
this.read_struct("MethodTypeParam", 2, |this| {
1258-
Ok(ty::MethodTypeParam(
1259-
ty::MethodParam {
1260-
trait_ref: {
1261-
this.read_struct_field("trait_ref", 0, |this| {
1262-
Ok(this.read_trait_ref(dcx))
1263-
}).unwrap()
1264-
},
1265-
method_num: {
1266-
this.read_struct_field("method_num", 1, |this| {
1267-
this.read_uint()
1268-
}).unwrap()
1269-
},
1270-
impl_def_id: {
1271-
this.read_struct_field("impl_def_id", 2, |this| {
1272-
this.read_option(|this, b| {
1273-
if b {
1274-
Ok(Some(this.read_def_id(dcx)))
1275-
} else {
1276-
Ok(None)
1277-
}
1278-
})
1279-
}).unwrap()
1280-
}
1281-
}))
1282-
}).unwrap()
1283-
}
1284-
1285-
3 => {
1286-
this.read_struct("MethodTraitObject", 2, |this| {
1287-
Ok(ty::MethodTraitObject(
1288-
ty::MethodObject {
1289-
trait_ref: {
1290-
this.read_struct_field("trait_ref", 0, |this| {
1291-
Ok(this.read_trait_ref(dcx))
1292-
}).unwrap()
1293-
},
1294-
object_trait_id: {
1295-
this.read_struct_field("object_trait_id", 1, |this| {
1296-
Ok(this.read_def_id(dcx))
1297-
}).unwrap()
1298-
},
1299-
method_num: {
1300-
this.read_struct_field("method_num", 2, |this| {
1301-
this.read_uint()
1302-
}).unwrap()
1303-
},
1304-
vtable_index: {
1305-
this.read_struct_field("vtable_index", 3, |this| {
1306-
this.read_uint()
1307-
}).unwrap()
1308-
},
1309-
}))
1310-
}).unwrap()
1311-
}
1312-
1313-
_ => panic!("..")
1314-
})
1315-
})
1316-
}).unwrap()
1317-
}
1318-
1319-
13201165
fn read_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>) -> Ty<'tcx> {
13211166
// Note: regions types embed local node ids. In principle, we
13221167
// should translate these node ids into the new decode
@@ -1663,7 +1508,7 @@ fn decode_side_tables(dcx: &DecodeContext,
16631508
}
16641509
c::tag_table_method_map => {
16651510
let (autoderef, method) = val_dsr.read_method_callee(dcx);
1666-
let method_call = MethodCall {
1511+
let method_call = ty::MethodCall {
16671512
expr_id: id,
16681513
autoderef: autoderef
16691514
};

src/librustc/middle/check_const.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -696,13 +696,10 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
696696
}
697697
}
698698
ast::ExprMethodCall(..) => {
699-
let method_did = match v.tcx.tables.borrow().method_map[&method_call].origin {
700-
ty::MethodStatic(did) => Some(did),
701-
_ => None
702-
};
703-
let is_const = match method_did {
704-
Some(did) => v.handle_const_fn_call(e, did, node_ty),
705-
None => false
699+
let method = v.tcx.tables.borrow().method_map[&method_call];
700+
let is_const = match v.tcx.impl_or_trait_item(method.def_id).container() {
701+
ty::ImplContainer(_) => v.handle_const_fn_call(e, method.def_id, node_ty),
702+
ty::TraitContainer(_) => false
706703
};
707704
if !is_const {
708705
v.add_qualif(ConstQualif::NOT_CONST);

src/librustc/middle/dead.rs

+4-34
Original file line numberDiff line numberDiff line change
@@ -93,40 +93,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
9393
});
9494
}
9595

96-
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
97-
span: codemap::Span) {
96+
fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
9897
let method_call = ty::MethodCall::expr(id);
99-
match self.tcx.tables.borrow().method_map.get(&method_call) {
100-
Some(method) => {
101-
match method.origin {
102-
ty::MethodStatic(def_id) => {
103-
match self.tcx.provided_source(def_id) {
104-
Some(p_did) => self.check_def_id(p_did),
105-
None => self.check_def_id(def_id)
106-
}
107-
}
108-
ty::MethodStaticClosure(_) => {}
109-
ty::MethodTypeParam(ty::MethodParam {
110-
ref trait_ref,
111-
method_num: index,
112-
..
113-
}) |
114-
ty::MethodTraitObject(ty::MethodObject {
115-
ref trait_ref,
116-
method_num: index,
117-
..
118-
}) => {
119-
let trait_item = self.tcx.trait_item(trait_ref.def_id, index);
120-
self.check_def_id(trait_item.def_id());
121-
}
122-
}
123-
}
124-
None => {
125-
self.tcx.sess.span_bug(span,
126-
"method call expression not \
127-
in method map?!")
128-
}
129-
}
98+
let method = self.tcx.tables.borrow().method_map[&method_call];
99+
self.check_def_id(method.def_id);
130100
}
131101

132102
fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) {
@@ -262,7 +232,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
262232
fn visit_expr(&mut self, expr: &ast::Expr) {
263233
match expr.node {
264234
ast::ExprMethodCall(..) => {
265-
self.lookup_and_handle_method(expr.id, expr.span);
235+
self.lookup_and_handle_method(expr.id);
266236
}
267237
ast::ExprField(ref lhs, ref ident) => {
268238
self.handle_field_access(&**lhs, ident.node.name);

src/librustc/middle/effect.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
120120
match expr.node {
121121
ast::ExprMethodCall(_, _, _) => {
122122
let method_call = MethodCall::expr(expr.id);
123-
let base_type = self.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
123+
let base_type = self.tcx.tables.borrow().method_map[&method_call].ty;
124124
debug!("effect: method call case, base type is {:?}",
125125
base_type);
126126
if type_is_unsafe_function(base_type) {

0 commit comments

Comments
 (0)