rustc: remove MethodOrigin and use the container to distinguish inherent methods.
This commit is contained in:
parent
536e71b78f
commit
d256eb1c5d
17 changed files with 59 additions and 120 deletions
|
@ -609,20 +609,17 @@ fn encode_method_callee<'a, 'tcx>(ecx: &e::EncodeContext<'a, 'tcx>,
|
|||
method: &ty::MethodCallee<'tcx>) {
|
||||
use serialize::Encoder;
|
||||
|
||||
rbml_w.emit_struct("MethodCallee", 5, |rbml_w| {
|
||||
rbml_w.emit_struct("MethodCallee", 4, |rbml_w| {
|
||||
rbml_w.emit_struct_field("autoderef", 0, |rbml_w| {
|
||||
autoderef.encode(rbml_w)
|
||||
});
|
||||
rbml_w.emit_struct_field("def_id", 1, |rbml_w| {
|
||||
Ok(rbml_w.emit_def_id(method.def_id))
|
||||
});
|
||||
rbml_w.emit_struct_field("origin", 2, |rbml_w| {
|
||||
method.origin.encode(rbml_w)
|
||||
});
|
||||
rbml_w.emit_struct_field("ty", 3, |rbml_w| {
|
||||
rbml_w.emit_struct_field("ty", 2, |rbml_w| {
|
||||
Ok(rbml_w.emit_ty(ecx, method.ty))
|
||||
});
|
||||
rbml_w.emit_struct_field("substs", 4, |rbml_w| {
|
||||
rbml_w.emit_struct_field("substs", 3, |rbml_w| {
|
||||
Ok(rbml_w.emit_substs(ecx, &method.substs))
|
||||
})
|
||||
}).unwrap();
|
||||
|
@ -632,19 +629,17 @@ impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
|
|||
fn read_method_callee<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
|
||||
-> (u32, ty::MethodCallee<'tcx>) {
|
||||
|
||||
self.read_struct("MethodCallee", 5, |this| {
|
||||
self.read_struct("MethodCallee", 4, |this| {
|
||||
let autoderef = this.read_struct_field("autoderef", 0,
|
||||
Decodable::decode).unwrap();
|
||||
Ok((autoderef, ty::MethodCallee {
|
||||
def_id: this.read_struct_field("def_id", 1, |this| {
|
||||
Ok(this.read_def_id(dcx))
|
||||
}).unwrap(),
|
||||
origin: this.read_struct_field("origin", 2,
|
||||
Decodable::decode).unwrap(),
|
||||
ty: this.read_struct_field("ty", 3, |this| {
|
||||
ty: this.read_struct_field("ty", 2, |this| {
|
||||
Ok(this.read_ty(dcx))
|
||||
}).unwrap(),
|
||||
substs: this.read_struct_field("substs", 4, |this| {
|
||||
substs: this.read_struct_field("substs", 3, |this| {
|
||||
Ok(dcx.tcx.mk_substs(this.read_substs(dcx)))
|
||||
}).unwrap()
|
||||
}))
|
||||
|
|
|
@ -696,11 +696,10 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
|
|||
}
|
||||
}
|
||||
ast::ExprMethodCall(..) => {
|
||||
let is_const = match v.tcx.tables.borrow().method_map[&method_call] {
|
||||
ty::MethodCallee { def_id, origin: ty::MethodOrigin::Inherent, .. } => {
|
||||
v.handle_const_fn_call(e, def_id, node_ty)
|
||||
}
|
||||
_ => false
|
||||
let method = v.tcx.tables.borrow().method_map[&method_call];
|
||||
let is_const = match v.tcx.impl_or_trait_item(method.def_id).container() {
|
||||
ty::ImplContainer(_) => v.handle_const_fn_call(e, method.def_id, node_ty),
|
||||
ty::TraitContainer(_) => false
|
||||
};
|
||||
if !is_const {
|
||||
v.add_qualif(ConstQualif::NOT_CONST);
|
||||
|
|
|
@ -93,17 +93,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
|||
});
|
||||
}
|
||||
|
||||
fn lookup_and_handle_method(&mut self, id: ast::NodeId,
|
||||
span: codemap::Span) {
|
||||
fn lookup_and_handle_method(&mut self, id: ast::NodeId) {
|
||||
let method_call = ty::MethodCall::expr(id);
|
||||
match self.tcx.tables.borrow().method_map.get(&method_call) {
|
||||
Some(method) => self.check_def_id(method.def_id),
|
||||
None => {
|
||||
self.tcx.sess.span_bug(span,
|
||||
"method call expression not \
|
||||
in method map?!")
|
||||
}
|
||||
}
|
||||
let method = self.tcx.tables.borrow().method_map[&method_call];
|
||||
self.check_def_id(method.def_id);
|
||||
}
|
||||
|
||||
fn handle_field_access(&mut self, lhs: &ast::Expr, name: ast::Name) {
|
||||
|
@ -239,7 +232,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
|||
fn visit_expr(&mut self, expr: &ast::Expr) {
|
||||
match expr.node {
|
||||
ast::ExprMethodCall(..) => {
|
||||
self.lookup_and_handle_method(expr.id, expr.span);
|
||||
self.lookup_and_handle_method(expr.id);
|
||||
}
|
||||
ast::ExprField(ref lhs, ref ident) => {
|
||||
self.handle_field_access(&**lhs, ident.node.name);
|
||||
|
|
|
@ -140,7 +140,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
|
|||
match expr.node {
|
||||
ast::ExprMethodCall(_, _, _) => {
|
||||
let method_call = MethodCall::expr(expr.id);
|
||||
let base_type = self.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
|
||||
let base_type = self.tcx.tables.borrow().method_map[&method_call].ty;
|
||||
debug!("effect: method call case, base type is {:?}",
|
||||
base_type);
|
||||
if type_is_unsafe_function(base_type) {
|
||||
|
|
|
@ -1148,7 +1148,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
|||
|
||||
ast::ExprMethodCall(_, _, ref args) => {
|
||||
let method_call = ty::MethodCall::expr(expr.id);
|
||||
let method_ty = self.ir.tcx.tables.borrow().method_map.get(&method_call).unwrap().ty;
|
||||
let method_ty = self.ir.tcx.tables.borrow().method_map[&method_call].ty;
|
||||
let succ = if method_ty.fn_ret().diverges() {
|
||||
self.s.exit_ln
|
||||
} else {
|
||||
|
|
|
@ -128,8 +128,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
|||
}
|
||||
ast::ExprMethodCall(..) => {
|
||||
let method_call = ty::MethodCall::expr(expr.id);
|
||||
match self.tcx.tables.borrow().method_map[&method_call] {
|
||||
ty::MethodCallee { def_id, origin: ty::MethodOrigin::Inherent, .. } => {
|
||||
let def_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
|
||||
match self.tcx.impl_or_trait_item(def_id).container() {
|
||||
ty::ImplContainer(_) => {
|
||||
if is_local(def_id) {
|
||||
if self.def_id_represents_local_inlined_item(def_id) {
|
||||
self.worklist.push(def_id.node)
|
||||
|
@ -137,7 +138,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
|
|||
self.reachable_symbols.insert(def_id.node);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
ty::TraitContainer(_) => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -406,10 +406,7 @@ pub fn check_expr(tcx: &ty::ctxt, e: &ast::Expr,
|
|||
ast::ExprMethodCall(i, _, _) => {
|
||||
span = i.span;
|
||||
let method_call = ty::MethodCall::expr(e.id);
|
||||
match tcx.tables.borrow().method_map.get(&method_call) {
|
||||
Some(method) => method.def_id,
|
||||
None => return
|
||||
}
|
||||
tcx.tables.borrow().method_map[&method_call].def_id
|
||||
}
|
||||
ast::ExprField(ref base_e, ref field) => {
|
||||
span = field.span;
|
||||
|
|
|
@ -625,20 +625,10 @@ pub enum CustomCoerceUnsized {
|
|||
Struct(usize)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)]
|
||||
pub enum MethodOrigin {
|
||||
/// Inherent impl method call.
|
||||
Inherent,
|
||||
|
||||
/// Trait method call.
|
||||
Trait
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct MethodCallee<'tcx> {
|
||||
/// Impl method ID, for inherent methods, or trait method ID, otherwise.
|
||||
pub def_id: ast::DefId,
|
||||
pub origin: MethodOrigin,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub substs: &'tcx subst::Substs<'tcx>
|
||||
}
|
||||
|
|
|
@ -1995,9 +1995,9 @@ impl LintPass for UnconditionalRecursion {
|
|||
fn expr_refers_to_this_method(tcx: &ty::ctxt,
|
||||
method: &ty::Method,
|
||||
id: ast::NodeId) -> bool {
|
||||
let tables = tcx.tables.borrow();
|
||||
let callee = match tables.method_map.get(&ty::MethodCall::expr(id)) {
|
||||
Some(m) => m,
|
||||
let method_call = ty::MethodCall::expr(id);
|
||||
let callee = match tcx.tables.borrow().method_map.get(&method_call) {
|
||||
Some(&m) => m,
|
||||
None => return false
|
||||
};
|
||||
let callee_item = tcx.impl_or_trait_item(callee.def_id);
|
||||
|
|
|
@ -844,17 +844,16 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Checks that a method is in scope.
|
||||
fn check_method(&mut self, span: Span, callee: &ty::MethodCallee,
|
||||
fn check_method(&mut self, span: Span, method_def_id: ast::DefId,
|
||||
name: ast::Name) {
|
||||
match callee.origin {
|
||||
ty::MethodOrigin::Inherent => {
|
||||
self.check_static_method(span, callee.def_id, name)
|
||||
match self.tcx.impl_or_trait_item(method_def_id).container() {
|
||||
ty::ImplContainer(_) => {
|
||||
self.check_static_method(span, method_def_id, name)
|
||||
}
|
||||
// Trait methods are always all public. The only controlling factor
|
||||
// is whether the trait itself is accessible or not.
|
||||
ty::MethodOrigin::Trait => {
|
||||
let method = self.tcx.impl_or_trait_item(callee.def_id);
|
||||
self.report_error(self.ensure_public(span, method.container().id(),
|
||||
ty::TraitContainer(trait_def_id) => {
|
||||
self.report_error(self.ensure_public(span, trait_def_id,
|
||||
None, "source trait"));
|
||||
}
|
||||
}
|
||||
|
@ -899,17 +898,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
ast::ExprMethodCall(ident, _, _) => {
|
||||
let method_call = ty::MethodCall::expr(expr.id);
|
||||
match self.tcx.tables.borrow().method_map.get(&method_call) {
|
||||
None => {
|
||||
self.tcx.sess.span_bug(expr.span,
|
||||
"method call not in \
|
||||
method map");
|
||||
}
|
||||
Some(method) => {
|
||||
debug!("(privacy checking) checking impl method");
|
||||
self.check_method(expr.span, method, ident.node.name);
|
||||
}
|
||||
}
|
||||
let method = self.tcx.tables.borrow().method_map[&method_call];
|
||||
debug!("(privacy checking) checking impl method");
|
||||
self.check_method(expr.span, method.def_id, ident.node.name);
|
||||
}
|
||||
ast::ExprStruct(_, ref fields, _) => {
|
||||
match self.tcx.expr_ty(expr).sty {
|
||||
|
|
|
@ -886,15 +886,11 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> {
|
|||
fn process_method_call(&mut self,
|
||||
ex: &ast::Expr,
|
||||
args: &Vec<P<ast::Expr>>) {
|
||||
let method_map = &self.tcx.tables.borrow().method_map;
|
||||
let method_callee = method_map.get(&ty::MethodCall::expr(ex.id)).unwrap();
|
||||
let (def_id, decl_id) = match method_callee.origin {
|
||||
ty::MethodOrigin::Inherent => {
|
||||
(Some(method_callee.def_id), None)
|
||||
}
|
||||
ty::MethodOrigin::Trait => {
|
||||
(None, Some(method_callee.def_id))
|
||||
}
|
||||
let method_call = ty::MethodCall::expr(ex.id);
|
||||
let method_id = self.tcx.tables.borrow().method_map[&method_call].def_id;
|
||||
let (def_id, decl_id) = match self.tcx.impl_or_trait_item(method_id).container() {
|
||||
ty::ImplContainer(_) => (Some(method_id), None),
|
||||
ty::TraitContainer(_) => (None, Some(method_id))
|
||||
};
|
||||
let sub_span = self.span.sub_span_for_meth_name(ex.span);
|
||||
self.fmt.meth_call_str(ex.span,
|
||||
|
|
|
@ -499,7 +499,7 @@ pub fn trans_fn_ref_with_substs<'a, 'tcx>(
|
|||
let ref_ty = match node {
|
||||
ExprId(id) => tcx.node_id_to_type(id),
|
||||
MethodCallKey(method_call) => {
|
||||
tcx.tables.borrow().method_map.get(&method_call).unwrap().ty
|
||||
tcx.tables.borrow().method_map[&method_call].ty
|
||||
}
|
||||
};
|
||||
let ref_ty = monomorphize::apply_param_substs(tcx,
|
||||
|
|
|
@ -1025,7 +1025,7 @@ pub fn node_id_substs<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||
tcx.node_id_item_substs(id).substs
|
||||
}
|
||||
MethodCallKey(method_call) => {
|
||||
tcx.tables.borrow().method_map.get(&method_call).unwrap().substs.clone()
|
||||
tcx.tables.borrow().method_map[&method_call].substs.clone()
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -106,20 +106,13 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
-> Callee<'blk, 'tcx> {
|
||||
let _icx = push_ctxt("meth::trans_method_callee");
|
||||
|
||||
let (method_id, origin, method_substs, method_ty) =
|
||||
bcx.tcx()
|
||||
.tables
|
||||
.borrow()
|
||||
.method_map
|
||||
.get(&method_call)
|
||||
.map(|method| (method.def_id, method.origin, method.substs, method.ty))
|
||||
.unwrap();
|
||||
let method = bcx.tcx().tables.borrow().method_map[&method_call];
|
||||
|
||||
match origin {
|
||||
ty::MethodOrigin::Inherent => {
|
||||
debug!("trans_method_callee: static, {:?}", method_id);
|
||||
match bcx.tcx().impl_or_trait_item(method.def_id).container() {
|
||||
ty::ImplContainer(_) => {
|
||||
debug!("trans_method_callee: static, {:?}", method.def_id);
|
||||
let datum = callee::trans_fn_ref(bcx.ccx(),
|
||||
method_id,
|
||||
method.def_id,
|
||||
MethodCallKey(method_call),
|
||||
bcx.fcx.param_substs);
|
||||
Callee {
|
||||
|
@ -129,11 +122,8 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
}
|
||||
}
|
||||
|
||||
ty::MethodOrigin::Trait => {
|
||||
let method_item = bcx.tcx().impl_or_trait_item(method_id);
|
||||
let trait_def_id = method_item.container().id();
|
||||
|
||||
let trait_substs = method_substs.clone().method_to_trait();
|
||||
ty::TraitContainer(trait_def_id) => {
|
||||
let trait_substs = method.substs.clone().method_to_trait();
|
||||
let trait_substs = bcx.tcx().mk_substs(trait_substs);
|
||||
let trait_ref = ty::TraitRef::new(trait_def_id, trait_substs);
|
||||
|
||||
|
@ -152,8 +142,8 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
|||
method_call,
|
||||
self_expr,
|
||||
trait_def_id,
|
||||
method_id,
|
||||
method_ty,
|
||||
method.def_id,
|
||||
method.ty,
|
||||
origin,
|
||||
arg_cleanup_scope)
|
||||
}
|
||||
|
|
|
@ -84,8 +84,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
self.enforce_illegal_method_limitations(&pick);
|
||||
|
||||
// Create substitutions for the method's type parameters.
|
||||
let (rcvr_substs, method_origin) =
|
||||
self.fresh_receiver_substs(self_ty, &pick);
|
||||
let rcvr_substs = self.fresh_receiver_substs(self_ty, &pick);
|
||||
let (method_types, method_regions) =
|
||||
self.instantiate_method_substs(&pick, supplied_method_types);
|
||||
let all_substs = rcvr_substs.with_method(method_types, method_regions);
|
||||
|
@ -112,7 +111,6 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
}));
|
||||
let callee = ty::MethodCallee {
|
||||
def_id: pick.item.def_id(),
|
||||
origin: method_origin,
|
||||
ty: fty,
|
||||
substs: self.tcx().mk_substs(all_substs)
|
||||
};
|
||||
|
@ -193,16 +191,14 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
fn fresh_receiver_substs(&mut self,
|
||||
self_ty: Ty<'tcx>,
|
||||
pick: &probe::Pick<'tcx>)
|
||||
-> (subst::Substs<'tcx>, ty::MethodOrigin)
|
||||
-> subst::Substs<'tcx>
|
||||
{
|
||||
match pick.kind {
|
||||
probe::InherentImplPick => {
|
||||
let impl_def_id = pick.item.container().id();
|
||||
assert!(self.tcx().impl_trait_ref(impl_def_id).is_none(),
|
||||
"impl {:?} is not an inherent impl", impl_def_id);
|
||||
let impl_polytype = check::impl_self_ty(self.fcx, self.span, impl_def_id);
|
||||
|
||||
(impl_polytype.substs, ty::MethodOrigin::Inherent)
|
||||
check::impl_self_ty(self.fcx, self.span, impl_def_id).substs
|
||||
}
|
||||
|
||||
probe::ObjectPick => {
|
||||
|
@ -228,9 +224,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
original_poly_trait_ref,
|
||||
upcast_trait_ref,
|
||||
trait_def_id);
|
||||
let substs = upcast_trait_ref.substs.clone();
|
||||
|
||||
(substs, ty::MethodOrigin::Trait)
|
||||
upcast_trait_ref.substs.clone()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -250,8 +244,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
self.span,
|
||||
&impl_polytype.substs,
|
||||
&self.tcx().impl_trait_ref(impl_def_id).unwrap());
|
||||
let substs = impl_trait_ref.substs.clone();
|
||||
(substs, ty::MethodOrigin::Trait)
|
||||
impl_trait_ref.substs.clone()
|
||||
}
|
||||
|
||||
probe::TraitPick => {
|
||||
|
@ -263,19 +256,15 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
|||
// the process we will unify the transformed-self-type
|
||||
// of the method with the actual type in order to
|
||||
// unify some of these variables.
|
||||
let substs = self.infcx().fresh_substs_for_trait(self.span,
|
||||
&trait_def.generics,
|
||||
self.infcx().next_ty_var());
|
||||
|
||||
(substs, ty::MethodOrigin::Trait)
|
||||
self.infcx().fresh_substs_for_trait(self.span,
|
||||
&trait_def.generics,
|
||||
self.infcx().next_ty_var())
|
||||
}
|
||||
|
||||
probe::WhereClausePick(ref poly_trait_ref) => {
|
||||
// Where clauses can have bound regions in them. We need to instantiate
|
||||
// those to convert from a poly-trait-ref to a trait-ref.
|
||||
let trait_ref = self.replace_late_bound_regions_with_fresh_var(&*poly_trait_ref);
|
||||
let substs = trait_ref.substs.clone();
|
||||
(substs, ty::MethodOrigin::Trait)
|
||||
self.replace_late_bound_regions_with_fresh_var(&*poly_trait_ref).substs.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -307,7 +307,6 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
|||
|
||||
let callee = ty::MethodCallee {
|
||||
def_id: method_item.def_id(),
|
||||
origin: ty::MethodOrigin::Trait,
|
||||
ty: fty,
|
||||
substs: trait_ref.substs
|
||||
};
|
||||
|
|
|
@ -303,7 +303,6 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
|
|||
method);
|
||||
let new_method = MethodCallee {
|
||||
def_id: method.def_id,
|
||||
origin: method.origin,
|
||||
ty: self.resolve(&method.ty, reason),
|
||||
substs: self.tcx().mk_substs(self.resolve(method.substs, reason)),
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue