rustc: remove MethodOrigin and use the container to distinguish inherent methods.

This commit is contained in:
Eduard Burtescu 2015-07-04 07:07:10 +03:00
parent 536e71b78f
commit d256eb1c5d
17 changed files with 59 additions and 120 deletions

View file

@ -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()
}))

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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 {

View file

@ -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(_) => {}
}
}
_ => {}

View file

@ -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;

View file

@ -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>
}

View file

@ -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);

View file

@ -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 {

View file

@ -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,

View file

@ -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,

View file

@ -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()
}
};

View file

@ -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)
}

View file

@ -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()
}
}
}

View file

@ -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
};

View file

@ -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)),
};