提交 a34b0a46 编写于 作者: E Eduard Burtescu

rustc: replace def::MethodProvenance with ty::ImplOrTraitItemContainer.

上级 1fe32ca1
......@@ -299,15 +299,7 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: ast::DefId) -> DefLike {
Constant => {
// Check whether we have an associated const item.
if item_sort(item) == Some('C') {
// Check whether the associated const is from a trait or impl.
// See the comment for methods below.
let provenance = if reader::maybe_get_doc(
item, tag_item_trait_parent_sort).is_some() {
def::FromTrait(item_require_parent_item(cdata, item))
} else {
def::FromImpl(item_require_parent_item(cdata, item))
};
DlDef(def::DefAssociatedConst(did, provenance))
DlDef(def::DefAssociatedConst(did))
} else {
// Regular const item.
DlDef(def::DefConst(did))
......@@ -319,18 +311,7 @@ fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: ast::DefId) -> DefLike {
Fn => DlDef(def::DefFn(did, false)),
CtorFn => DlDef(def::DefFn(did, true)),
Method | StaticMethod => {
// def_static_method carries an optional field of its enclosing
// trait or enclosing impl (if this is an inherent static method).
// So we need to detect whether this is in a trait or not, which
// we do through the mildly hacky way of checking whether there is
// a trait_parent_sort.
let provenance = if reader::maybe_get_doc(
item, tag_item_trait_parent_sort).is_some() {
def::FromTrait(item_require_parent_item(cdata, item))
} else {
def::FromImpl(item_require_parent_item(cdata, item))
};
DlDef(def::DefMethod(did, provenance))
DlDef(def::DefMethod(did))
}
Type => {
if item_sort(item) == Some('t') {
......
......@@ -444,9 +444,7 @@ impl tr for def::Def {
fn tr(&self, dcx: &DecodeContext) -> def::Def {
match *self {
def::DefFn(did, is_ctor) => def::DefFn(did.tr(dcx), is_ctor),
def::DefMethod(did, p) => {
def::DefMethod(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
}
def::DefMethod(did) => def::DefMethod(did.tr(dcx)),
def::DefSelfTy(opt_did, impl_ids) => { def::DefSelfTy(opt_did.map(|did| did.tr(dcx)),
impl_ids.map(|(nid1, nid2)| {
(dcx.tr_id(nid1),
......@@ -456,9 +454,7 @@ fn tr(&self, dcx: &DecodeContext) -> def::Def {
def::DefForeignMod(did) => { def::DefForeignMod(did.tr(dcx)) }
def::DefStatic(did, m) => { def::DefStatic(did.tr(dcx), m) }
def::DefConst(did) => { def::DefConst(did.tr(dcx)) }
def::DefAssociatedConst(did, p) => {
def::DefAssociatedConst(did.tr(dcx), p.map(|did2| did2.tr(dcx)))
}
def::DefAssociatedConst(did) => def::DefAssociatedConst(did.tr(dcx)),
def::DefLocal(nid) => { def::DefLocal(dcx.tr_id(nid)) }
def::DefVariant(e_did, v_did, is_s) => {
def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
......
......@@ -650,7 +650,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
}
}
Some(def::DefConst(did)) |
Some(def::DefAssociatedConst(did, _)) => {
Some(def::DefAssociatedConst(did)) => {
if let Some(expr) = const_eval::lookup_const_by_id(v.tcx, did,
Some(e.id)) {
let inner = v.global_expr(Mode::Const, expr);
......@@ -696,10 +696,17 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>,
v.add_qualif(ConstQualif::NON_ZERO_SIZED);
true
}
Some(def::DefMethod(did, def::FromImpl(_))) |
Some(def::DefFn(did, _)) => {
v.handle_const_fn_call(e, did, node_ty)
}
Some(def::DefMethod(did)) => {
match v.tcx.impl_or_trait_item(did).container() {
ty::ImplContainer(_) => {
v.handle_const_fn_call(e, did, node_ty)
}
ty::TraitContainer(_) => false
}
}
_ => false
};
if !is_const {
......
......@@ -442,7 +442,7 @@ fn fold_pat(&mut self, pat: P<Pat>) -> P<Pat> {
ast::PatIdent(..) | ast::PatEnum(..) | ast::PatQPath(..) => {
let def = self.tcx.def_map.borrow().get(&pat.id).map(|d| d.full_def());
match def {
Some(DefAssociatedConst(did, _)) |
Some(DefAssociatedConst(did)) |
Some(DefConst(did)) => match lookup_const_by_id(self.tcx, did, Some(pat.id)) {
Some(const_expr) => {
const_expr_to_pat(self.tcx, const_expr, pat.span).map(|new_pat| {
......
......@@ -238,7 +238,7 @@ fn visit_expr(&mut self, e: &'ast ast::Expr) {
ast::ExprPath(..) => {
match self.def_map.borrow().get(&e.id).map(|d| d.base_def) {
Some(DefStatic(def_id, _)) |
Some(DefAssociatedConst(def_id, _)) |
Some(DefAssociatedConst(def_id)) |
Some(DefConst(def_id))
if ast_util::is_local(def_id) => {
match self.ast_map.get(def_id.node) {
......
......@@ -41,7 +41,7 @@ fn lookup_const<'a>(tcx: &'a ty::ctxt, e: &Expr) -> Option<&'a Expr> {
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
match opt_def {
Some(def::DefConst(def_id)) |
Some(def::DefAssociatedConst(def_id, _)) => {
Some(def::DefAssociatedConst(def_id)) => {
lookup_const_by_id(tcx, def_id, Some(e.id))
}
Some(def::DefVariant(enum_def, variant_def, _)) => {
......@@ -929,10 +929,10 @@ fn fromb(b: bool) -> ConstVal { Int(b as i64) }
(lookup_const_by_id(tcx, def_id, Some(e.id)), None)
}
}
Some(def::DefAssociatedConst(def_id, provenance)) => {
Some(def::DefAssociatedConst(def_id)) => {
if ast_util::is_local(def_id) {
match provenance {
def::FromTrait(trait_id) => match tcx.map.find(def_id.node) {
match tcx.impl_or_trait_item(def_id).container() {
ty::TraitContainer(trait_id) => match tcx.map.find(def_id.node) {
Some(ast_map::NodeTraitItem(ti)) => match ti.node {
ast::ConstTraitItem(ref ty, _) => {
if let ExprTypeChecked = ty_hint {
......@@ -950,7 +950,7 @@ fn fromb(b: bool) -> ConstVal { Int(b as i64) }
},
_ => (None, None)
},
def::FromImpl(_) => match tcx.map.find(def_id.node) {
ty::ImplContainer(_) => match tcx.map.find(def_id.node) {
Some(ast_map::NodeImplItem(ii)) => match ii.node {
ast::ConstImplItem(ref ty, ref expr) => {
(Some(&**expr), Some(&**ty))
......
......@@ -9,7 +9,6 @@
// except according to those terms.
pub use self::Def::*;
pub use self::MethodProvenance::*;
use middle::privacy::LastPrivate;
use middle::subst::ParamSpace;
......@@ -28,7 +27,7 @@ pub enum Def {
DefForeignMod(ast::DefId),
DefStatic(ast::DefId, bool /* is_mutbl */),
DefConst(ast::DefId),
DefAssociatedConst(ast::DefId /* const */, MethodProvenance),
DefAssociatedConst(ast::DefId),
DefLocal(ast::NodeId),
DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
DefTy(ast::DefId, bool /* is_enum */),
......@@ -51,7 +50,7 @@ pub enum Def {
DefStruct(ast::DefId),
DefRegion(ast::NodeId),
DefLabel(ast::NodeId),
DefMethod(ast::DefId /* method */, MethodProvenance),
DefMethod(ast::DefId),
}
/// The result of resolving a path.
......@@ -112,23 +111,6 @@ pub struct Export {
pub def_id: ast::DefId, // The definition of the target.
}
#[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum MethodProvenance {
FromTrait(ast::DefId),
FromImpl(ast::DefId),
}
impl MethodProvenance {
pub fn map<F>(self, f: F) -> MethodProvenance where
F: FnOnce(ast::DefId) -> ast::DefId,
{
match self {
FromTrait(did) => FromTrait(f(did)),
FromImpl(did) => FromImpl(f(did))
}
}
}
impl Def {
pub fn local_node_id(&self) -> ast::NodeId {
let def_id = self.def_id();
......@@ -141,7 +123,7 @@ pub fn def_id(&self) -> ast::DefId {
DefFn(id, _) | DefMod(id) | DefForeignMod(id) | DefStatic(id, _) |
DefVariant(_, id, _) | DefTy(id, _) | DefAssociatedTy(_, id) |
DefTyParam(_, _, id, _) | DefUse(id) | DefStruct(id) | DefTrait(id) |
DefMethod(id, _) | DefConst(id) | DefAssociatedConst(id, _) |
DefMethod(id) | DefConst(id) | DefAssociatedConst(id) |
DefSelfTy(Some(id), None)=> {
id
}
......
......@@ -545,14 +545,12 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
match trait_item.node {
ast::ConstTraitItem(..) => {
let def = DefAssociatedConst(local_def(trait_item.id),
FromTrait(local_def(item.id)));
let def = DefAssociatedConst(local_def(trait_item.id));
// NB: not DefModifiers::IMPORTABLE
name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
}
ast::MethodTraitItem(..) => {
let def = DefMethod(local_def(trait_item.id),
FromTrait(local_def(item.id)));
let def = DefMethod(local_def(trait_item.id));
// NB: not DefModifiers::IMPORTABLE
name_bindings.define_value(def, trait_item.span, DefModifiers::PUBLIC);
}
......
......@@ -3448,7 +3448,7 @@ fn is_static_method(this: &Resolver, did: DefId) -> bool {
// Look for a method in the current self type's impl module.
if let Some(module) = get_module(self, path.span, &name_path) {
if let Some(binding) = module.children.borrow().get(&name) {
if let Some(DefMethod(did, _)) = binding.def_for_namespace(ValueNS) {
if let Some(DefMethod(did)) = binding.def_for_namespace(ValueNS) {
if is_static_method(self, did) {
return StaticMethod(path_names_to_string(&path, 0))
}
......
......@@ -719,7 +719,7 @@ fn process_path(&mut self,
let def_map = self.tcx.def_map.borrow();
let def = def_map.get(&id).unwrap().full_def();
match def {
def::DefMethod(did, _) => {
def::DefMethod(did) => {
let ti = self.tcx.impl_or_trait_item(did);
if let ty::MethodTraitItem(m) = ti {
if m.explicit_self == ty::StaticExplicitSelfCategory {
......
......@@ -551,12 +551,12 @@ pub fn get_path_data(&self,
scope: self.enclosing_scope(id),
}))
}
def::DefMethod(decl_id, provenence) => {
def::DefMethod(decl_id) => {
let sub_span = self.span_utils.sub_span_for_meth_name(path.span);
let def_id = if decl_id.krate == ast::LOCAL_CRATE {
let ti = self.tcx.impl_or_trait_item(decl_id);
match provenence {
def::FromTrait(def_id) => {
match ti.container() {
ty::TraitContainer(def_id) => {
self.tcx.trait_items(def_id)
.iter()
.find(|mr| {
......@@ -564,7 +564,7 @@ pub fn get_path_data(&self,
})
.map(|mr| mr.def_id())
}
def::FromImpl(def_id) => {
ty::ImplContainer(def_id) => {
let impl_items = self.tcx.impl_items.borrow();
Some(impl_items.get(&def_id)
.unwrap()
......
......@@ -159,16 +159,27 @@ fn trans_def<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let def_id = inline::maybe_instantiate_inline(bcx.ccx(), did);
Callee { bcx: bcx, data: Intrinsic(def_id.node, substs), ty: expr_ty }
}
def::DefFn(did, _) | def::DefMethod(did, def::FromImpl(_)) => {
def::DefFn(did, _) => {
fn_callee(bcx, trans_fn_ref(bcx.ccx(), did, ExprId(ref_expr.id),
bcx.fcx.param_substs))
}
def::DefMethod(meth_did, def::FromTrait(trait_did)) => {
fn_callee(bcx, meth::trans_static_method_callee(bcx.ccx(),
meth_did,
trait_did,
ref_expr.id,
bcx.fcx.param_substs))
def::DefMethod(meth_did) => {
let method_item = bcx.tcx().impl_or_trait_item(meth_did);
let fn_datum = match method_item.container() {
ty::ImplContainer(_) => {
trans_fn_ref(bcx.ccx(), meth_did,
ExprId(ref_expr.id),
bcx.fcx.param_substs)
}
ty::TraitContainer(trait_did) => {
meth::trans_static_method_callee(bcx.ccx(),
meth_did,
trait_did,
ref_expr.id,
bcx.fcx.param_substs)
}
};
fn_callee(bcx, fn_datum)
}
def::DefVariant(tid, vid, _) => {
let vinfo = bcx.tcx().enum_variant_with_id(tid, vid);
......
......@@ -229,7 +229,7 @@ pub fn get_const_expr_as_global<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ast::ExprPath(..) => {
let def = ccx.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
match def {
def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
if !ccx.tcx().tables.borrow().adjustments.contains_key(&expr.id) {
debug!("get_const_expr_as_global ({:?}): found const {:?}",
expr.id, def_id);
......@@ -802,7 +802,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
def::DefFn(..) | def::DefMethod(..) => {
expr::trans_def_fn_unadjusted(cx, e, def, param_substs).val
}
def::DefConst(def_id) | def::DefAssociatedConst(def_id, _) => {
def::DefConst(def_id) | def::DefAssociatedConst(def_id) => {
const_deref_ptr(cx, get_const_val(cx, def_id, e))
}
def::DefVariant(enum_did, variant_did, _) => {
......@@ -846,9 +846,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let def = cx.tcx().def_map.borrow()[&callee.id].full_def();
let arg_vals = map_list(args);
match def {
def::DefFn(did, _) | def::DefMethod(did, _) => {
def::DefFn(did, _) | def::DefMethod(did) => {
const_fn_call(cx, ExprId(callee.id), did, &arg_vals, param_substs)
},
}
def::DefStruct(_) => {
if ety.is_simd(cx.tcx()) {
C_vector(&arg_vals[..])
......@@ -856,7 +856,7 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
let repr = adt::represent_type(cx, ety);
adt::trans_const(cx, &*repr, 0, &arg_vals[..])
}
},
}
def::DefVariant(enum_did, variant_did, _) => {
let repr = adt::represent_type(cx, ety);
let vinfo = cx.tcx().enum_variant_with_id(enum_did, variant_did);
......@@ -864,14 +864,14 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
&*repr,
vinfo.disr_val,
&arg_vals[..])
},
}
_ => cx.sess().span_bug(e.span, "expected a struct, variant, or const fn def"),
}
},
ast::ExprMethodCall(_, _, ref args) => {
let arg_vals = map_list(args);
let method_call = ty::MethodCall::expr(e.id);
let method_did = cx.tcx().tables.borrow().method_map[&method_call].def_id;
let method_did = cx.tcx().tables.borrow().method_map[&method_call].def_id;
const_fn_call(cx, MethodCallKey(method_call),
method_did, &arg_vals, param_substs)
},
......
......@@ -1293,14 +1293,22 @@ pub fn trans_def_fn_unadjusted<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
match def {
def::DefFn(did, _) |
def::DefStruct(did) | def::DefVariant(_, did, _) |
def::DefMethod(did, def::FromImpl(_)) => {
def::DefStruct(did) | def::DefVariant(_, did, _) => {
callee::trans_fn_ref(ccx, did, ExprId(ref_expr.id), param_substs)
}
def::DefMethod(impl_did, def::FromTrait(trait_did)) => {
meth::trans_static_method_callee(ccx, impl_did,
trait_did, ref_expr.id,
param_substs)
def::DefMethod(method_did) => {
match ccx.tcx().impl_or_trait_item(method_did).container() {
ty::ImplContainer(_) => {
callee::trans_fn_ref(ccx, method_did,
ExprId(ref_expr.id),
param_substs)
}
ty::TraitContainer(trait_did) => {
meth::trans_static_method_callee(ccx, method_did,
trait_did, ref_expr.id,
param_substs)
}
}
}
_ => {
ccx.tcx().sess.span_bug(ref_expr.span, &format!(
......
......@@ -334,19 +334,14 @@ pub fn resolve_ufcs<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let pick = try!(probe::probe(fcx, span, mode, method_name, self_ty, expr_id));
let def_id = pick.item.def_id();
let mut lp = LastMod(AllPublic);
let container_def_id = pick.item.container().id();
let provenance = match pick.kind {
probe::InherentImplPick => {
if pick.item.vis() != ast::Public {
lp = LastMod(DependsOn(def_id));
}
def::FromImpl(container_def_id)
if let probe::InherentImplPick = pick.kind {
if pick.item.vis() != ast::Public {
lp = LastMod(DependsOn(def_id));
}
_ => def::FromTrait(container_def_id)
};
}
let def_result = match pick.item {
ty::ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id, provenance),
ty::ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id, provenance),
ty::ImplOrTraitItem::MethodTraitItem(..) => def::DefMethod(def_id),
ty::ImplOrTraitItem::ConstTraitItem(..) => def::DefAssociatedConst(def_id),
ty::ImplOrTraitItem::TypeTraitItem(..) => {
fcx.tcx().sess.span_bug(span, "resolve_ufcs: probe picked associated type");
}
......
......@@ -4447,9 +4447,9 @@ fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
(ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
ty::GenericPredicates::empty())
}
def::DefFn(id, _) | def::DefMethod(id, _) |
def::DefFn(id, _) | def::DefMethod(id) |
def::DefStatic(id, _) | def::DefVariant(_, id, _) |
def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id, _) => {
def::DefStruct(id) | def::DefConst(id) | def::DefAssociatedConst(id) => {
(fcx.tcx().lookup_item_type(id), fcx.tcx().lookup_predicates(id))
}
def::DefTrait(_) |
......@@ -4555,7 +4555,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
assert!(!segments.is_empty());
let mut ufcs_method = None;
let mut ufcs_associated = None;
let mut segment_spaces: Vec<_>;
match def {
// Case 1 and 1b. Reference to a *type* or *enum variant*.
......@@ -4582,12 +4582,13 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
}
// Case 3. Reference to a method.
def::DefMethod(_, provenance) => {
match provenance {
def::FromTrait(trait_did) => {
def::DefMethod(def_id) => {
let container = fcx.tcx().impl_or_trait_item(def_id).container();
match container {
ty::TraitContainer(trait_did) => {
callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
}
def::FromImpl(_) => {}
ty::ImplContainer(_) => {}
}
if segments.len() >= 2 {
......@@ -4598,16 +4599,17 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// `<T>::method` will end up here, and so can `T::method`.
let self_ty = opt_self_ty.expect("UFCS sugared method missing Self");
segment_spaces = vec![Some(subst::FnSpace)];
ufcs_method = Some((provenance, self_ty));
ufcs_associated = Some((container, self_ty));
}
}
def::DefAssociatedConst(_, provenance) => {
match provenance {
def::FromTrait(trait_did) => {
def::DefAssociatedConst(def_id) => {
let container = fcx.tcx().impl_or_trait_item(def_id).container();
match container {
ty::TraitContainer(trait_did) => {
callee::check_legal_trait_for_method_call(fcx.ccx, span, trait_did)
}
def::FromImpl(_) => {}
ty::ImplContainer(_) => {}
}
if segments.len() >= 2 {
......@@ -4615,7 +4617,10 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
segment_spaces.push(Some(subst::TypeSpace));
segment_spaces.push(None);
} else {
// `<T>::CONST` will end up here, and so can `T::CONST`.
let self_ty = opt_self_ty.expect("UFCS sugared const missing Self");
segment_spaces = vec![None];
ufcs_associated = Some((container, self_ty));
}
}
......@@ -4637,7 +4642,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// In `<T as Trait<A, B>>::method`, `A` and `B` are mandatory, but
// `opt_self_ty` can also be Some for `Foo::method`, where Foo's
// type parameters are not mandatory.
let require_type_space = opt_self_ty.is_some() && ufcs_method.is_none();
let require_type_space = opt_self_ty.is_some() && ufcs_associated.is_none();
debug!("segment_spaces={:?}", segment_spaces);
......@@ -4707,7 +4712,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let ty_substituted = fcx.instantiate_type_scheme(span, &substs, &type_scheme.ty);
if let Some((def::FromImpl(impl_def_id), self_ty)) = ufcs_method {
if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
// In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
// is inherent, there is no `Self` parameter, instead, the impl needs
// type parameters, which we can infer by unifying the provided `Self`
......
......@@ -107,7 +107,7 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
record_extern_fqn(cx, did, clean::TypeStatic);
clean::StaticItem(build_static(cx, tcx, did, mtbl))
}
def::DefConst(did) | def::DefAssociatedConst(did, _) => {
def::DefConst(did) | def::DefAssociatedConst(did) => {
record_extern_fqn(cx, did, clean::TypeConst);
clean::ConstantItem(build_const(cx, tcx, did))
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册