mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-22 20:53:37 +00:00
Store a method-from-trait's impl in some cases when it is known.
This allows one to look at an `ExprMethodCall` `foo.bar()` where `bar` is a method in some trait and (sometimes) extract the `impl` that `bar` is defined in, e.g. trait Foo { fn bar(&self); } impl Foo for uint { // <A> fn bar(&self) {} } fn main() { 1u.bar(); // impl_def_id == Some(<A>) } This definitely doesn't handle all cases, but is correct when it is known, meaning it should only be used for certain linting/heuristic purposes; no safety analysis.
This commit is contained in:
parent
4be79d6acd
commit
000dc07f71
@ -627,6 +627,7 @@ impl<'tcx> tr for MethodOrigin<'tcx> {
|
||||
// def-id is already translated when we read it out
|
||||
trait_ref: mp.trait_ref.clone(),
|
||||
method_num: mp.method_num,
|
||||
impl_def_id: mp.impl_def_id.tr(dcx),
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -879,6 +880,16 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
|
||||
try!(this.emit_struct_field("method_num", 0, |this| {
|
||||
this.emit_uint(p.method_num)
|
||||
}));
|
||||
try!(this.emit_struct_field("impl_def_id", 0, |this| {
|
||||
this.emit_option(|this| {
|
||||
match p.impl_def_id {
|
||||
None => this.emit_option_none(),
|
||||
Some(did) => this.emit_option_some(|this| {
|
||||
Ok(this.emit_def_id(did))
|
||||
})
|
||||
}
|
||||
})
|
||||
}));
|
||||
Ok(())
|
||||
})
|
||||
})
|
||||
@ -1452,6 +1463,17 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
|
||||
this.read_struct_field("method_num", 1, |this| {
|
||||
this.read_uint()
|
||||
}).unwrap()
|
||||
},
|
||||
impl_def_id: {
|
||||
this.read_struct_field("impl_def_id", 2, |this| {
|
||||
this.read_option(|this, b| {
|
||||
if b {
|
||||
Ok(Some(this.read_def_id(dcx)))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
})
|
||||
}).unwrap()
|
||||
}
|
||||
}))
|
||||
}).unwrap()
|
||||
|
@ -453,9 +453,14 @@ pub struct MethodParam<'tcx> {
|
||||
// never contains bound regions; those regions should have been
|
||||
// instantiated with fresh variables at this point.
|
||||
pub trait_ref: Rc<ty::TraitRef<'tcx>>,
|
||||
|
||||
// index of uint in the list of methods for the trait
|
||||
pub method_num: uint,
|
||||
|
||||
/// The impl for the trait from which the method comes. This
|
||||
/// should only be used for certain linting/heuristic purposes
|
||||
/// since there is no guarantee that this is Some in every
|
||||
/// situation that it could/should be.
|
||||
pub impl_def_id: Option<ast::DefId>,
|
||||
}
|
||||
|
||||
// details for a method invoked with a receiver whose type is an object
|
||||
|
@ -310,7 +310,8 @@ impl<'tcx> TypeFoldable<'tcx> for ty::MethodOrigin<'tcx> {
|
||||
ty::MethodTypeParam(ref param) => {
|
||||
ty::MethodTypeParam(ty::MethodParam {
|
||||
trait_ref: param.trait_ref.fold_with(folder),
|
||||
method_num: param.method_num
|
||||
method_num: param.method_num,
|
||||
impl_def_id: param.impl_def_id,
|
||||
})
|
||||
}
|
||||
ty::MethodTraitObject(ref object) => {
|
||||
|
@ -132,7 +132,8 @@ pub fn trans_method_callee<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
|
||||
|
||||
ty::MethodTypeParam(ty::MethodParam {
|
||||
ref trait_ref,
|
||||
method_num
|
||||
method_num,
|
||||
impl_def_id: _
|
||||
}) => {
|
||||
let trait_ref = ty::Binder(bcx.monomorphize(trait_ref));
|
||||
let span = bcx.tcx().map.span(method_call.expr_id);
|
||||
|
@ -256,7 +256,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
&impl_polytype.substs,
|
||||
&ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap());
|
||||
let origin = MethodTypeParam(MethodParam { trait_ref: impl_trait_ref.clone(),
|
||||
method_num: method_num });
|
||||
method_num: method_num,
|
||||
impl_def_id: Some(impl_def_id) });
|
||||
(impl_trait_ref.substs.clone(), origin)
|
||||
}
|
||||
|
||||
@ -275,7 +276,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
let trait_ref =
|
||||
Rc::new(ty::TraitRef::new(trait_def_id, self.tcx().mk_substs(substs.clone())));
|
||||
let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref,
|
||||
method_num: method_num });
|
||||
method_num: method_num,
|
||||
impl_def_id: None });
|
||||
(substs, origin)
|
||||
}
|
||||
|
||||
@ -285,7 +287,8 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
|
||||
let trait_ref = self.replace_late_bound_regions_with_fresh_var(&*poly_trait_ref);
|
||||
let substs = trait_ref.substs.clone();
|
||||
let origin = MethodTypeParam(MethodParam { trait_ref: trait_ref,
|
||||
method_num: method_num });
|
||||
method_num: method_num,
|
||||
impl_def_id: None });
|
||||
(substs, origin)
|
||||
}
|
||||
}
|
||||
|
@ -287,7 +287,8 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
|
||||
|
||||
let callee = MethodCallee {
|
||||
origin: MethodTypeParam(MethodParam{trait_ref: trait_ref.clone(),
|
||||
method_num: method_num}),
|
||||
method_num: method_num,
|
||||
impl_def_id: None}),
|
||||
ty: fty,
|
||||
substs: trait_ref.substs.clone()
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user