diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 55f0ef4fd57..b3ddd3869cb 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -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') { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 9889ea92215..5c3b0a1c2d2 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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 @@ impl tr for 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) diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index baaf6b6a040..9667312b370 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -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 { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 12dd12f746f..f17cb673a5f 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -442,7 +442,7 @@ impl<'a, 'tcx> Folder for StaticInliner<'a, 'tcx> { 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| { diff --git a/src/librustc/middle/check_static_recursion.rs b/src/librustc/middle/check_static_recursion.rs index 55a9a919300..77bb53a77bc 100644 --- a/src/librustc/middle/check_static_recursion.rs +++ b/src/librustc/middle/check_static_recursion.rs @@ -238,7 +238,7 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { 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) { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 298126be2fd..fd1c8d4892a 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -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 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>, (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 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>, }, _ => (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)) diff --git a/src/librustc/middle/def.rs b/src/librustc/middle/def.rs index bce246fa4af..36c6630c822 100644 --- a/src/librustc/middle/def.rs +++ b/src/librustc/middle/def.rs @@ -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 @@ impl Def { 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 } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 27195d9635d..656d6a36614 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -545,14 +545,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> { 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); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index fa9c7a2038c..c1f8af1562d 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3448,7 +3448,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // 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)) } diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index f1f39d43ee4..1fbec6f66cf 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -719,7 +719,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { 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 { diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 8d3be7c8c60..796850ad6f2 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -551,12 +551,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { 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 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { }) .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() diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index 0f75c1f8ab6..a60217be409 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -159,16 +159,27 @@ fn trans<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, expr: &ast::Expr) 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); diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index bd9c4a17177..71ba4d73dac 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -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) }, diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 2dae1aca835..619447df3c5 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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!( diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index e3f55cca9ee..fd5d8d8d196 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -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"); } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 819f4437297..6851fb46670 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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` diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e80fd360e04..31cd8ce1b53 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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)) }