Auto merge of #95884 - cjgillot:assoc-item, r=lcnr

Thin `AssocItem`

This PR removes a few fields from `AssocItem` that should be easily computed using other queries.
This simplifies some of the metadata decoding.
This commit is contained in:
bors 2022-08-01 21:43:35 +00:00
commit 21de280ccc
61 changed files with 354 additions and 403 deletions

View File

@ -323,7 +323,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) { fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) {
// Do not visit the duplicate information in TraitItemRef. We want to // Do not visit the duplicate information in TraitItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref. // map the actual nodes, not the duplicate ones in the *Ref.
let TraitItemRef { id, ident: _, kind: _, span: _, defaultness: _ } = *ii; let TraitItemRef { id, ident: _, kind: _, span: _ } = *ii;
self.visit_nested_trait_item(id); self.visit_nested_trait_item(id);
} }
@ -331,8 +331,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) { fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) {
// Do not visit the duplicate information in ImplItemRef. We want to // Do not visit the duplicate information in ImplItemRef. We want to
// map the actual nodes, not the duplicate ones in the *Ref. // map the actual nodes, not the duplicate ones in the *Ref.
let ImplItemRef { id, ident: _, kind: _, span: _, defaultness: _, trait_item_def_id: _ } = let ImplItemRef { id, ident: _, kind: _, span: _, trait_item_def_id: _ } = *ii;
*ii;
self.visit_nested_impl_item(id); self.visit_nested_impl_item(id);
} }

View File

@ -755,17 +755,17 @@ impl<'hir> LoweringContext<'_, 'hir> {
let hir_id = self.lower_node_id(i.id); let hir_id = self.lower_node_id(i.id);
let trait_item_def_id = hir_id.expect_owner(); let trait_item_def_id = hir_id.expect_owner();
let (generics, kind) = match i.kind { let (generics, kind, has_default) = match i.kind {
AssocItemKind::Const(_, ref ty, ref default) => { AssocItemKind::Const(_, ref ty, ref default) => {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)); let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x))); let body = default.as_ref().map(|x| self.lower_const_body(i.span, Some(x)));
(hir::Generics::empty(), hir::TraitItemKind::Const(ty, body)) (hir::Generics::empty(), hir::TraitItemKind::Const(ty, body), body.is_some())
} }
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => { AssocItemKind::Fn(box Fn { ref sig, ref generics, body: None, .. }) => {
let names = self.lower_fn_params_to_names(&sig.decl); let names = self.lower_fn_params_to_names(&sig.decl);
let (generics, sig) = let (generics, sig) =
self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None); self.lower_method_sig(generics, sig, i.id, FnDeclKind::Trait, None);
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names))) (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Required(names)), false)
} }
AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => { AssocItemKind::Fn(box Fn { ref sig, ref generics, body: Some(ref body), .. }) => {
let asyncness = sig.header.asyncness; let asyncness = sig.header.asyncness;
@ -778,7 +778,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
FnDeclKind::Trait, FnDeclKind::Trait,
asyncness.opt_return_id(), asyncness.opt_return_id(),
); );
(generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id))) (generics, hir::TraitItemKind::Fn(sig, hir::TraitFn::Provided(body_id)), true)
} }
AssocItemKind::TyAlias(box TyAlias { AssocItemKind::TyAlias(box TyAlias {
ref generics, ref generics,
@ -789,7 +789,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
}) => { }) => {
let mut generics = generics.clone(); let mut generics = generics.clone();
add_ty_alias_where_clause(&mut generics, where_clauses, false); add_ty_alias_where_clause(&mut generics, where_clauses, false);
self.lower_generics( let (generics, kind) = self.lower_generics(
&generics, &generics,
i.id, i.id,
ImplTraitContext::Disallowed(ImplTraitPosition::Generic), ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
@ -805,7 +805,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
ty, ty,
) )
}, },
) );
(generics, kind, ty.is_some())
} }
AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
}; };
@ -817,28 +818,25 @@ impl<'hir> LoweringContext<'_, 'hir> {
generics, generics,
kind, kind,
span: self.lower_span(i.span), span: self.lower_span(i.span),
defaultness: hir::Defaultness::Default { has_value: has_default },
}; };
self.arena.alloc(item) self.arena.alloc(item)
} }
fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef {
let (kind, has_default) = match &i.kind { let kind = match &i.kind {
AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()), AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::TyAlias(box TyAlias { ty, .. }) => { AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,
(hir::AssocItemKind::Type, ty.is_some()) AssocItemKind::Fn(box Fn { sig, .. }) => {
} hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }
AssocItemKind::Fn(box Fn { sig, body, .. }) => {
(hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, body.is_some())
} }
AssocItemKind::MacCall(..) => unimplemented!(), AssocItemKind::MacCall(..) => unimplemented!(),
}; };
let id = hir::TraitItemId { def_id: self.local_def_id(i.id) }; let id = hir::TraitItemId { def_id: self.local_def_id(i.id) };
let defaultness = hir::Defaultness::Default { has_value: has_default };
hir::TraitItemRef { hir::TraitItemRef {
id, id,
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
span: self.lower_span(i.span), span: self.lower_span(i.span),
defaultness,
kind, kind,
} }
} }
@ -849,6 +847,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> { fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
let (generics, kind) = match &i.kind { let (generics, kind) = match &i.kind {
AssocItemKind::Const(_, ty, expr) => { AssocItemKind::Const(_, ty, expr) => {
let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)); let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type));
@ -903,19 +905,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
kind, kind,
vis_span: self.lower_span(i.vis.span), vis_span: self.lower_span(i.vis.span),
span: self.lower_span(i.span), span: self.lower_span(i.span),
defaultness,
}; };
self.arena.alloc(item) self.arena.alloc(item)
} }
fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef { fn lower_impl_item_ref(&mut self, i: &AssocItem) -> hir::ImplItemRef {
// Since `default impl` is not yet implemented, this is always true in impls.
let has_value = true;
let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
hir::ImplItemRef { hir::ImplItemRef {
id: hir::ImplItemId { def_id: self.local_def_id(i.id) }, id: hir::ImplItemId { def_id: self.local_def_id(i.id) },
ident: self.lower_ident(i.ident), ident: self.lower_ident(i.ident),
span: self.lower_span(i.span), span: self.lower_span(i.span),
defaultness,
kind: match &i.kind { kind: match &i.kind {
AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::Const(..) => hir::AssocItemKind::Const,
AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type, AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type,

View File

@ -772,7 +772,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
let mut nonconst_call_permission = false; let mut nonconst_call_permission = false;
if let Some(callee_trait) = tcx.trait_of_item(callee) if let Some(callee_trait) = tcx.trait_of_item(callee)
&& tcx.has_attr(callee_trait, sym::const_trait) && tcx.has_attr(callee_trait, sym::const_trait)
&& Some(callee_trait) == tcx.trait_of_item(caller) && Some(callee_trait) == tcx.trait_of_item(caller.to_def_id())
// Can only call methods when it's `<Self as TheTrait>::f`. // Can only call methods when it's `<Self as TheTrait>::f`.
&& tcx.types.self_param == substs.type_at(0) && tcx.types.self_param == substs.type_at(0)
{ {

View File

@ -66,9 +66,12 @@ pub fn call_kind<'tcx>(
from_hir_call: bool, from_hir_call: bool,
self_arg: Option<Ident>, self_arg: Option<Ident>,
) -> CallKind<'tcx> { ) -> CallKind<'tcx> {
let parent = tcx.opt_associated_item(method_did).and_then(|assoc| match assoc.container { let parent = tcx.opt_associated_item(method_did).and_then(|assoc| {
AssocItemContainer::ImplContainer(impl_did) => tcx.trait_id_of_impl(impl_did), let container_id = assoc.container_id(tcx);
AssocItemContainer::TraitContainer(trait_did) => Some(trait_did), match assoc.container {
AssocItemContainer::ImplContainer => tcx.trait_id_of_impl(container_id),
AssocItemContainer::TraitContainer => Some(container_id),
}
}); });
let fn_call = parent let fn_call = parent

View File

@ -2222,6 +2222,7 @@ pub struct TraitItem<'hir> {
pub generics: &'hir Generics<'hir>, pub generics: &'hir Generics<'hir>,
pub kind: TraitItemKind<'hir>, pub kind: TraitItemKind<'hir>,
pub span: Span, pub span: Span,
pub defaultness: Defaultness,
} }
impl TraitItem<'_> { impl TraitItem<'_> {
@ -2281,6 +2282,7 @@ pub struct ImplItem<'hir> {
pub def_id: LocalDefId, pub def_id: LocalDefId,
pub generics: &'hir Generics<'hir>, pub generics: &'hir Generics<'hir>,
pub kind: ImplItemKind<'hir>, pub kind: ImplItemKind<'hir>,
pub defaultness: Defaultness,
pub span: Span, pub span: Span,
pub vis_span: Span, pub vis_span: Span,
} }
@ -3083,7 +3085,6 @@ pub struct TraitItemRef {
pub ident: Ident, pub ident: Ident,
pub kind: AssocItemKind, pub kind: AssocItemKind,
pub span: Span, pub span: Span,
pub defaultness: Defaultness,
} }
/// A reference from an impl to one of its associated items. This /// A reference from an impl to one of its associated items. This
@ -3098,7 +3099,6 @@ pub struct ImplItemRef {
pub ident: Ident, pub ident: Ident,
pub kind: AssocItemKind, pub kind: AssocItemKind,
pub span: Span, pub span: Span,
pub defaultness: Defaultness,
/// When we are in a trait impl, link to the trait-item's id. /// When we are in a trait impl, link to the trait-item's id.
pub trait_item_def_id: Option<DefId>, pub trait_item_def_id: Option<DefId>,
} }
@ -3496,11 +3496,11 @@ mod size_asserts {
rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72); rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72);
rustc_data_structures::static_assert_size!(GenericBound<'_>, 48); rustc_data_structures::static_assert_size!(GenericBound<'_>, 48);
rustc_data_structures::static_assert_size!(Generics<'static>, 56); rustc_data_structures::static_assert_size!(Generics<'static>, 56);
rustc_data_structures::static_assert_size!(ImplItem<'static>, 80); rustc_data_structures::static_assert_size!(ImplItem<'static>, 88);
rustc_data_structures::static_assert_size!(Impl<'static>, 80); rustc_data_structures::static_assert_size!(Impl<'static>, 80);
rustc_data_structures::static_assert_size!(Item<'static>, 80); rustc_data_structures::static_assert_size!(Item<'static>, 80);
rustc_data_structures::static_assert_size!(Pat<'static>, 88); rustc_data_structures::static_assert_size!(Pat<'static>, 88);
rustc_data_structures::static_assert_size!(QPath<'static>, 24); rustc_data_structures::static_assert_size!(QPath<'static>, 24);
rustc_data_structures::static_assert_size!(TraitItem<'static>, 88); rustc_data_structures::static_assert_size!(TraitItem<'static>, 96);
rustc_data_structures::static_assert_size!(Ty<'static>, 72); rustc_data_structures::static_assert_size!(Ty<'static>, 72);
} }

View File

@ -946,32 +946,30 @@ pub fn walk_fn<'v, V: Visitor<'v>>(
} }
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) { pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem<'v>) {
visitor.visit_ident(trait_item.ident); // N.B., deliberately force a compilation error if/when new fields are added.
visitor.visit_generics(&trait_item.generics); let TraitItem { ident, generics, ref defaultness, ref kind, span, def_id: _ } = *trait_item;
match trait_item.kind { let hir_id = trait_item.hir_id();
visitor.visit_ident(ident);
visitor.visit_generics(&generics);
visitor.visit_defaultness(&defaultness);
match *kind {
TraitItemKind::Const(ref ty, default) => { TraitItemKind::Const(ref ty, default) => {
visitor.visit_id(trait_item.hir_id()); visitor.visit_id(hir_id);
visitor.visit_ty(ty); visitor.visit_ty(ty);
walk_list!(visitor, visit_nested_body, default); walk_list!(visitor, visit_nested_body, default);
} }
TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => { TraitItemKind::Fn(ref sig, TraitFn::Required(param_names)) => {
visitor.visit_id(trait_item.hir_id()); visitor.visit_id(hir_id);
visitor.visit_fn_decl(&sig.decl); visitor.visit_fn_decl(&sig.decl);
for &param_name in param_names { for &param_name in param_names {
visitor.visit_ident(param_name); visitor.visit_ident(param_name);
} }
} }
TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => { TraitItemKind::Fn(ref sig, TraitFn::Provided(body_id)) => {
visitor.visit_fn( visitor.visit_fn(FnKind::Method(ident, sig), &sig.decl, body_id, span, hir_id);
FnKind::Method(trait_item.ident, sig),
&sig.decl,
body_id,
trait_item.span,
trait_item.hir_id(),
);
} }
TraitItemKind::Type(bounds, ref default) => { TraitItemKind::Type(bounds, ref default) => {
visitor.visit_id(trait_item.hir_id()); visitor.visit_id(hir_id);
walk_list!(visitor, visit_param_bound, bounds); walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_ty, default); walk_list!(visitor, visit_ty, default);
} }
@ -980,19 +978,27 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) { pub fn walk_trait_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, trait_item_ref: &'v TraitItemRef) {
// N.B., deliberately force a compilation error if/when new fields are added. // N.B., deliberately force a compilation error if/when new fields are added.
let TraitItemRef { id, ident, ref kind, span: _, ref defaultness } = *trait_item_ref; let TraitItemRef { id, ident, ref kind, span: _ } = *trait_item_ref;
visitor.visit_nested_trait_item(id); visitor.visit_nested_trait_item(id);
visitor.visit_ident(ident); visitor.visit_ident(ident);
visitor.visit_associated_item_kind(kind); visitor.visit_associated_item_kind(kind);
visitor.visit_defaultness(defaultness);
} }
pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) { pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplItem<'v>) {
// N.B., deliberately force a compilation error if/when new fields are added. // N.B., deliberately force a compilation error if/when new fields are added.
let ImplItem { def_id: _, ident, ref generics, ref kind, span: _, vis_span: _ } = *impl_item; let ImplItem {
def_id: _,
ident,
ref generics,
ref kind,
ref defaultness,
span: _,
vis_span: _,
} = *impl_item;
visitor.visit_ident(ident); visitor.visit_ident(ident);
visitor.visit_generics(generics); visitor.visit_generics(generics);
visitor.visit_defaultness(defaultness);
match *kind { match *kind {
ImplItemKind::Const(ref ty, body) => { ImplItemKind::Const(ref ty, body) => {
visitor.visit_id(impl_item.hir_id()); visitor.visit_id(impl_item.hir_id());
@ -1027,12 +1033,10 @@ pub fn walk_foreign_item_ref<'v, V: Visitor<'v>>(
pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) { pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &'v ImplItemRef) {
// N.B., deliberately force a compilation error if/when new fields are added. // N.B., deliberately force a compilation error if/when new fields are added.
let ImplItemRef { id, ident, ref kind, span: _, ref defaultness, trait_item_def_id: _ } = let ImplItemRef { id, ident, ref kind, span: _, trait_item_def_id: _ } = *impl_item_ref;
*impl_item_ref;
visitor.visit_nested_impl_item(id); visitor.visit_nested_impl_item(id);
visitor.visit_ident(ident); visitor.visit_ident(ident);
visitor.visit_associated_item_kind(kind); visitor.visit_associated_item_kind(kind);
visitor.visit_defaultness(defaultness);
} }
pub fn walk_struct_def<'v, V: Visitor<'v>>( pub fn walk_struct_def<'v, V: Visitor<'v>>(

View File

@ -80,7 +80,7 @@ const BASE_STRUCT: &[&str] =
/// Extra `DepNode`s for functions and methods. /// Extra `DepNode`s for functions and methods.
const EXTRA_ASSOCIATED: &[&str] = &[label_strs::associated_item]; const EXTRA_ASSOCIATED: &[&str] = &[label_strs::associated_item];
const EXTRA_TRAIT: &[&str] = &[label_strs::trait_of_item]; const EXTRA_TRAIT: &[&str] = &[];
// Fully Built Labels // Fully Built Labels

View File

@ -76,10 +76,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
"...is used and required to live as long as `'static` here \ "...is used and required to live as long as `'static` here \
because of an implicit lifetime bound on the {}", because of an implicit lifetime bound on the {}",
match ctxt.assoc_item.container { match ctxt.assoc_item.container {
AssocItemContainer::TraitContainer(id) => AssocItemContainer::TraitContainer => {
format!("`impl` of `{}`", tcx.def_path_str(id)), let id = ctxt.assoc_item.container_id(tcx);
AssocItemContainer::ImplContainer(_) => format!("`impl` of `{}`", tcx.def_path_str(id))
"inherent `impl`".to_string(), }
AssocItemContainer::ImplContainer => "inherent `impl`".to_string(),
}, },
), ),
); );

View File

@ -22,8 +22,8 @@ pub fn method_context(cx: &LateContext<'_>, id: hir::HirId) -> MethodLateContext
let def_id = cx.tcx.hir().local_def_id(id); let def_id = cx.tcx.hir().local_def_id(id);
let item = cx.tcx.associated_item(def_id); let item = cx.tcx.associated_item(def_id);
match item.container { match item.container {
ty::TraitContainer(..) => MethodLateContext::TraitAutoImpl, ty::TraitContainer => MethodLateContext::TraitAutoImpl,
ty::ImplContainer(cid) => match cx.tcx.impl_trait_ref(cid) { ty::ImplContainer => match cx.tcx.impl_trait_ref(item.container_id(cx.tcx)) {
Some(_) => MethodLateContext::TraitImpl, Some(_) => MethodLateContext::TraitImpl,
None => MethodLateContext::PlainImpl, None => MethodLateContext::PlainImpl,
}, },

View File

@ -1114,7 +1114,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
fn get_fn_has_self_parameter(self, id: DefIndex) -> bool { fn get_fn_has_self_parameter(self, id: DefIndex) -> bool {
match self.kind(id) { match self.kind(id) {
EntryKind::AssocFn(data) => data.decode(self).has_self, EntryKind::AssocFn { has_self, .. } => has_self,
_ => false, _ => false,
} }
} }
@ -1134,28 +1134,21 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
fn get_associated_item(self, id: DefIndex) -> ty::AssocItem { fn get_associated_item(self, id: DefIndex) -> ty::AssocItem {
let def_key = self.def_key(id);
let parent = self.local_def_id(def_key.parent.unwrap());
let name = self.item_name(id); let name = self.item_name(id);
let (kind, container, has_self) = match self.kind(id) { let (kind, container, has_self) = match self.kind(id) {
EntryKind::AssocConst(container) => (ty::AssocKind::Const, container, false), EntryKind::AssocConst(container) => (ty::AssocKind::Const, container, false),
EntryKind::AssocFn(data) => { EntryKind::AssocFn { container, has_self } => (ty::AssocKind::Fn, container, has_self),
let data = data.decode(self);
(ty::AssocKind::Fn, data.container, data.has_self)
}
EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false), EntryKind::AssocType(container) => (ty::AssocKind::Type, container, false),
_ => bug!("cannot get associated-item of `{:?}`", def_key), _ => bug!("cannot get associated-item of `{:?}`", id),
}; };
ty::AssocItem { ty::AssocItem {
name, name,
kind, kind,
vis: self.get_visibility(id),
defaultness: container.defaultness(),
def_id: self.local_def_id(id), def_id: self.local_def_id(id),
trait_item_def_id: self.get_trait_item_def_id(id), trait_item_def_id: self.get_trait_item_def_id(id),
container: container.with_def_id(parent), container,
fn_has_self_parameter: has_self, fn_has_self_parameter: has_self,
} }
} }
@ -1310,19 +1303,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
} }
} }
fn get_trait_of_item(self, id: DefIndex) -> Option<DefId> {
let def_key = self.def_key(id);
match def_key.disambiguated_data.data {
DefPathData::TypeNs(..) | DefPathData::ValueNs(..) => (),
// Not an associated item
_ => return None,
}
def_key.parent.and_then(|parent_index| match self.kind(parent_index) {
EntryKind::Trait | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)),
_ => None,
})
}
fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a { fn get_native_libraries(self, sess: &'a Session) -> impl Iterator<Item = NativeLib> + 'a {
self.root.native_libraries.decode((self, sess)) self.root.native_libraries.decode((self, sess))
} }

View File

@ -235,7 +235,6 @@ provide! { <'tcx> tcx, def_id, other, cdata,
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
is_foreign_item => { cdata.is_foreign_item(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) }
item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) }
trait_of_item => { cdata.get_trait_of_item(def_id.index) }
is_mir_available => { cdata.is_item_mir_available(def_id.index) } is_mir_available => { cdata.is_item_mir_available(def_id.index) }
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) } is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }

View File

@ -1212,14 +1212,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let ast_item = tcx.hir().expect_trait_item(def_id.expect_local()); let ast_item = tcx.hir().expect_trait_item(def_id.expect_local());
self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
let trait_item = tcx.associated_item(def_id); let trait_item = tcx.associated_item(def_id);
let container = match trait_item.defaultness {
hir::Defaultness::Default { has_value: true } => AssocContainer::TraitWithDefault,
hir::Defaultness::Default { has_value: false } => AssocContainer::TraitRequired,
hir::Defaultness::Final => span_bug!(ast_item.span, "traits cannot have final items"),
};
match trait_item.kind { match trait_item.kind {
ty::AssocKind::Const => { ty::AssocKind::Const => {
let rendered = rustc_hir_pretty::to_string( let rendered = rustc_hir_pretty::to_string(
@ -1227,7 +1222,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|s| s.print_trait_item(ast_item), |s| s.print_trait_item(ast_item),
); );
record!(self.tables.kind[def_id] <- EntryKind::AssocConst(container)); record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::TraitContainer));
record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default()); record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default());
record!(self.tables.rendered_const[def_id] <- rendered); record!(self.tables.rendered_const[def_id] <- rendered);
} }
@ -1243,14 +1238,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
}; };
self.tables.asyncness.set(def_id.index, m_sig.header.asyncness); self.tables.asyncness.set(def_id.index, m_sig.header.asyncness);
self.tables.constness.set(def_id.index, hir::Constness::NotConst); self.tables.constness.set(def_id.index, hir::Constness::NotConst);
record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
container, container: ty::AssocItemContainer::TraitContainer,
has_self: trait_item.fn_has_self_parameter, has_self: trait_item.fn_has_self_parameter,
}))); });
} }
ty::AssocKind::Type => { ty::AssocKind::Type => {
self.encode_explicit_item_bounds(def_id); self.encode_explicit_item_bounds(def_id);
record!(self.tables.kind[def_id] <- EntryKind::AssocType(container)); record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::TraitContainer));
} }
} }
match trait_item.kind { match trait_item.kind {
@ -1258,7 +1253,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.encode_item_type(def_id); self.encode_item_type(def_id);
} }
ty::AssocKind::Type => { ty::AssocKind::Type => {
if trait_item.defaultness.has_value() { if ast_item.defaultness.has_value() {
self.encode_item_type(def_id); self.encode_item_type(def_id);
} }
} }
@ -1273,23 +1268,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local()); let ast_item = self.tcx.hir().expect_impl_item(def_id.expect_local());
self.tables.impl_defaultness.set(def_id.index, ast_item.defaultness);
let impl_item = self.tcx.associated_item(def_id); let impl_item = self.tcx.associated_item(def_id);
let container = match impl_item.defaultness {
hir::Defaultness::Default { has_value: true } => AssocContainer::ImplDefault,
hir::Defaultness::Final => AssocContainer::ImplFinal,
hir::Defaultness::Default { has_value: false } => {
span_bug!(ast_item.span, "impl items always have values (currently)")
}
};
match impl_item.kind { match impl_item.kind {
ty::AssocKind::Const => { ty::AssocKind::Const => {
if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind { if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind {
let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id); let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_id);
let const_data = self.encode_rendered_const_for_body(body_id); let const_data = self.encode_rendered_const_for_body(body_id);
record!(self.tables.kind[def_id] <- EntryKind::AssocConst(container)); record!(self.tables.kind[def_id] <- EntryKind::AssocConst(ty::AssocItemContainer::ImplContainer));
record!(self.tables.mir_const_qualif[def_id] <- qualifs); record!(self.tables.mir_const_qualif[def_id] <- qualifs);
record!(self.tables.rendered_const[def_id] <- const_data); record!(self.tables.rendered_const[def_id] <- const_data);
} else { } else {
@ -1307,13 +1295,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hir::Constness::NotConst hir::Constness::NotConst
}; };
self.tables.constness.set(def_id.index, constness); self.tables.constness.set(def_id.index, constness);
record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { record!(self.tables.kind[def_id] <- EntryKind::AssocFn {
container, container: ty::AssocItemContainer::ImplContainer,
has_self: impl_item.fn_has_self_parameter, has_self: impl_item.fn_has_self_parameter,
}))); });
} }
ty::AssocKind::Type => { ty::AssocKind::Type => {
record!(self.tables.kind[def_id] <- EntryKind::AssocType(container)); record!(self.tables.kind[def_id] <- EntryKind::AssocType(ty::AssocItemContainer::ImplContainer));
} }
} }
self.encode_item_type(def_id); self.encode_item_type(def_id);

View File

@ -419,9 +419,9 @@ enum EntryKind {
Generator, Generator,
Trait, Trait,
Impl, Impl,
AssocFn(LazyValue<AssocFnData>), AssocFn { container: ty::AssocItemContainer, has_self: bool },
AssocType(AssocContainer), AssocType(ty::AssocItemContainer),
AssocConst(AssocContainer), AssocConst(ty::AssocItemContainer),
TraitAlias, TraitAlias,
} }
@ -434,47 +434,6 @@ struct VariantData {
is_non_exhaustive: bool, is_non_exhaustive: bool,
} }
/// Describes whether the container of an associated item
/// is a trait or an impl and whether, in a trait, it has
/// a default, or an in impl, whether it's marked "default".
#[derive(Copy, Clone, TyEncodable, TyDecodable)]
enum AssocContainer {
TraitRequired,
TraitWithDefault,
ImplDefault,
ImplFinal,
}
impl AssocContainer {
fn with_def_id(&self, def_id: DefId) -> ty::AssocItemContainer {
match *self {
AssocContainer::TraitRequired | AssocContainer::TraitWithDefault => {
ty::TraitContainer(def_id)
}
AssocContainer::ImplDefault | AssocContainer::ImplFinal => ty::ImplContainer(def_id),
}
}
fn defaultness(&self) -> hir::Defaultness {
match *self {
AssocContainer::TraitRequired => hir::Defaultness::Default { has_value: false },
AssocContainer::TraitWithDefault | AssocContainer::ImplDefault => {
hir::Defaultness::Default { has_value: true }
}
AssocContainer::ImplFinal => hir::Defaultness::Final,
}
}
}
#[derive(MetadataEncodable, MetadataDecodable)]
struct AssocFnData {
container: AssocContainer,
has_self: bool,
}
#[derive(TyEncodable, TyDecodable)] #[derive(TyEncodable, TyDecodable)]
struct GeneratorData<'tcx> { struct GeneratorData<'tcx> {
layout: mir::GeneratorLayout<'tcx>, layout: mir::GeneratorLayout<'tcx>,
@ -492,7 +451,6 @@ pub fn provide(providers: &mut Providers) {
trivially_parameterized_over_tcx! { trivially_parameterized_over_tcx! {
VariantData, VariantData,
AssocFnData,
EntryKind, EntryKind,
RawDefId, RawDefId,
TraitImpls, TraitImpls,

View File

@ -1147,14 +1147,6 @@ rustc_queries! {
separate_provide_extern separate_provide_extern
} }
/// Given an `associated_item`, find the trait it belongs to.
/// Return `None` if the `DefId` is not an associated item.
query trait_of_item(associated_item: DefId) -> Option<DefId> {
desc { |tcx| "finding trait defining `{}`", tcx.def_path_str(associated_item) }
cache_on_disk_if { associated_item.is_local() }
separate_provide_extern
}
query is_ctfe_mir_available(key: DefId) -> bool { query is_ctfe_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) } desc { |tcx| "checking if item has ctfe mir available: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }

View File

@ -217,7 +217,7 @@ impl<'tcx> Ancestors<'tcx> {
self.find_map(|node| { self.find_map(|node| {
if let Some(item) = node.item(tcx, trait_item_def_id) { if let Some(item) = node.item(tcx, trait_item_def_id) {
if finalizing_node.is_none() { if finalizing_node.is_none() {
let is_specializable = item.defaultness.is_default() let is_specializable = item.defaultness(tcx).is_default()
|| tcx.impl_defaultness(node.def_id()).is_default(); || tcx.impl_defaultness(node.def_id()).is_default();
if !is_specializable { if !is_specializable {

View File

@ -1,6 +1,6 @@
pub use self::AssocItemContainer::*; pub use self::AssocItemContainer::*;
use crate::ty; use crate::ty::{self, DefIdTree};
use rustc_data_structures::sorted_map::SortedIndexMultiMap; use rustc_data_structures::sorted_map::SortedIndexMultiMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def::{DefKind, Namespace};
@ -11,33 +11,8 @@ use super::{TyCtxt, Visibility};
#[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)] #[derive(Clone, Copy, PartialEq, Eq, Debug, HashStable, Hash, Encodable, Decodable)]
pub enum AssocItemContainer { pub enum AssocItemContainer {
TraitContainer(DefId), TraitContainer,
ImplContainer(DefId), ImplContainer,
}
impl AssocItemContainer {
pub fn impl_def_id(&self) -> Option<DefId> {
match *self {
ImplContainer(id) => Some(id),
_ => None,
}
}
/// Asserts that this is the `DefId` of an associated item declared
/// in a trait, and returns the trait `DefId`.
pub fn assert_trait(&self) -> DefId {
match *self {
TraitContainer(id) => id,
_ => bug!("associated item has wrong container type: {:?}", self),
}
}
pub fn id(&self) -> DefId {
match *self {
TraitContainer(id) => id,
ImplContainer(id) => id,
}
}
} }
/// Information about an associated item /// Information about an associated item
@ -46,8 +21,6 @@ pub struct AssocItem {
pub def_id: DefId, pub def_id: DefId,
pub name: Symbol, pub name: Symbol,
pub kind: AssocKind, pub kind: AssocKind,
pub vis: Visibility,
pub defaultness: hir::Defaultness,
pub container: AssocItemContainer, pub container: AssocItemContainer,
/// If this is an item in an impl of a trait then this is the `DefId` of /// If this is an item in an impl of a trait then this is the `DefId` of
@ -64,6 +37,36 @@ impl AssocItem {
Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap())
} }
pub fn defaultness(&self, tcx: TyCtxt<'_>) -> hir::Defaultness {
tcx.impl_defaultness(self.def_id)
}
#[inline]
pub fn visibility(&self, tcx: TyCtxt<'_>) -> Visibility {
tcx.visibility(self.def_id)
}
#[inline]
pub fn container_id(&self, tcx: TyCtxt<'_>) -> DefId {
tcx.parent(self.def_id)
}
#[inline]
pub fn trait_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
match self.container {
AssocItemContainer::ImplContainer => None,
AssocItemContainer::TraitContainer => Some(tcx.parent(self.def_id)),
}
}
#[inline]
pub fn impl_container(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
match self.container {
AssocItemContainer::ImplContainer => Some(tcx.parent(self.def_id)),
AssocItemContainer::TraitContainer => None,
}
}
pub fn signature(&self, tcx: TyCtxt<'_>) -> String { pub fn signature(&self, tcx: TyCtxt<'_>) -> String {
match self.kind { match self.kind {
ty::AssocKind::Fn => { ty::AssocKind::Fn => {

View File

@ -1668,8 +1668,7 @@ impl<'tcx> TyCtxt<'tcx> {
// Checks if the bound region is in Impl Item. // Checks if the bound region is in Impl Item.
pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool { pub fn is_bound_region_in_impl_item(self, suitable_region_binding_scope: LocalDefId) -> bool {
let container_id = let container_id = self.parent(suitable_region_binding_scope.to_def_id());
self.associated_item(suitable_region_binding_scope.to_def_id()).container.id();
if self.impl_trait_ref(container_id).is_some() { if self.impl_trait_ref(container_id).is_some() {
// For now, we do not try to target impls of traits. This is // For now, we do not try to target impls of traits. This is
// because this message is going to suggest that the user // because this message is going to suggest that the user

View File

@ -673,7 +673,7 @@ impl<T> Trait<T> for X {
// the associated type or calling a method that returns the associated type". // the associated type or calling a method that returns the associated type".
let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type( let point_at_assoc_fn = self.point_at_methods_that_satisfy_associated_type(
diag, diag,
assoc.container.id(), assoc.container_id(self),
current_method_ident, current_method_ident,
proj_ty.item_def_id, proj_ty.item_def_id,
values.expected, values.expected,
@ -844,7 +844,8 @@ fn foo(&self) -> Self::T { String::new() }
hir::AssocItemKind::Type => { hir::AssocItemKind::Type => {
// FIXME: account for returning some type in a trait fn impl that has // FIXME: account for returning some type in a trait fn impl that has
// an assoc type as a return type (#72076). // an assoc type as a return type (#72076).
if let hir::Defaultness::Default { has_value: true } = item.defaultness if let hir::Defaultness::Default { has_value: true } =
self.impl_defaultness(item.id.def_id)
{ {
if self.type_of(item.id.def_id) == found { if self.type_of(item.id.def_id) == found {
diag.span_label( diag.span_label(

View File

@ -460,7 +460,7 @@ impl<'tcx> Instance<'tcx> {
&& !matches!( && !matches!(
tcx.opt_associated_item(def.did), tcx.opt_associated_item(def.did),
Some(ty::AssocItem { Some(ty::AssocItem {
container: ty::AssocItemContainer::TraitContainer(_), container: ty::AssocItemContainer::TraitContainer,
.. ..
}) })
) )

View File

@ -1945,7 +1945,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> { pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator<Item = &'tcx AssocItem> {
self.associated_items(id) self.associated_items(id)
.in_definition_order() .in_definition_order()
.filter(|item| item.kind == AssocKind::Fn && item.defaultness.has_value()) .filter(move |item| item.kind == AssocKind::Fn && item.defaultness(self).has_value())
} }
/// Look up the name of a definition across crates. This does not look at HIR. /// Look up the name of a definition across crates. This does not look at HIR.
@ -2191,13 +2191,29 @@ impl<'tcx> TyCtxt<'tcx> {
self.impl_trait_ref(def_id).map(|tr| tr.def_id) self.impl_trait_ref(def_id).map(|tr| tr.def_id)
} }
/// If the given `DefId` describes an item belonging to a trait,
/// returns the `DefId` of the trait that the trait item belongs to;
/// otherwise, returns `None`.
pub fn trait_of_item(self, def_id: DefId) -> Option<DefId> {
if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
let parent = self.parent(def_id);
if let DefKind::Trait | DefKind::TraitAlias = self.def_kind(parent) {
return Some(parent);
}
}
None
}
/// If the given `DefId` describes a method belonging to an impl, returns the /// If the given `DefId` describes a method belonging to an impl, returns the
/// `DefId` of the impl that the method belongs to; otherwise, returns `None`. /// `DefId` of the impl that the method belongs to; otherwise, returns `None`.
pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> { pub fn impl_of_method(self, def_id: DefId) -> Option<DefId> {
self.opt_associated_item(def_id).and_then(|trait_item| match trait_item.container { if let DefKind::AssocConst | DefKind::AssocFn | DefKind::AssocTy = self.def_kind(def_id) {
TraitContainer(_) => None, let parent = self.parent(def_id);
ImplContainer(def_id) => Some(def_id), if let DefKind::Impl = self.def_kind(parent) {
}) return Some(parent);
}
}
None
} }
/// If the given `DefId` belongs to a trait that was automatically derived, returns `true`. /// If the given `DefId` belongs to a trait that was automatically derived, returns `true`.

View File

@ -1179,13 +1179,14 @@ pub struct ProjectionTy<'tcx> {
/// The `DefId` of the `TraitItem` for the associated type `N`. /// The `DefId` of the `TraitItem` for the associated type `N`.
/// ///
/// Note that this is not the `DefId` of the `TraitRef` containing this /// Note that this is not the `DefId` of the `TraitRef` containing this
/// associated type, which is in `tcx.associated_item(item_def_id).container`. /// associated type, which is in `tcx.associated_item(item_def_id).container`,
/// aka. `tcx.parent(item_def_id).unwrap()`.
pub item_def_id: DefId, pub item_def_id: DefId,
} }
impl<'tcx> ProjectionTy<'tcx> { impl<'tcx> ProjectionTy<'tcx> {
pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId { pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
tcx.associated_item(self.item_def_id).container.id() tcx.parent(self.item_def_id)
} }
/// Extracts the underlying trait reference and own substs from this projection. /// Extracts the underlying trait reference and own substs from this projection.
@ -1195,7 +1196,7 @@ impl<'tcx> ProjectionTy<'tcx> {
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) { ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
let def_id = tcx.associated_item(self.item_def_id).container.id(); let def_id = tcx.parent(self.item_def_id);
let trait_generics = tcx.generics_of(def_id); let trait_generics = tcx.generics_of(def_id);
( (
ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, trait_generics) }, ty::TraitRef { def_id, substs: self.substs.truncate_to(tcx, trait_generics) },
@ -1433,7 +1434,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
/// then this function would return an `exists T. T: Iterator` existential trait /// then this function would return an `exists T. T: Iterator` existential trait
/// reference. /// reference.
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> { pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
let def_id = tcx.associated_item(self.item_def_id).container.id(); let def_id = tcx.parent(self.item_def_id);
let subst_count = tcx.generics_of(def_id).count() - 1; let subst_count = tcx.generics_of(def_id).count() - 1;
let substs = tcx.intern_substs(&self.substs[..subst_count]); let substs = tcx.intern_substs(&self.substs[..subst_count]);
ty::ExistentialTraitRef { def_id, substs } ty::ExistentialTraitRef { def_id, substs }

View File

@ -402,7 +402,7 @@ impl<'tcx> TyCtxt<'tcx> {
Some(dtor) => dtor.did, Some(dtor) => dtor.did,
}; };
let impl_def_id = self.associated_item(dtor).container.id(); let impl_def_id = self.parent(dtor);
let impl_generics = self.generics_of(impl_def_id); let impl_generics = self.generics_of(impl_def_id);
// We have a destructor - all the parameters that are not // We have a destructor - all the parameters that are not

View File

@ -4,7 +4,7 @@ use rustc_data_structures::graph::iterate::{
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_middle::mir::{BasicBlock, BasicBlocks, Body, Operand, TerminatorKind}; use rustc_middle::mir::{BasicBlock, BasicBlocks, Body, Operand, TerminatorKind};
use rustc_middle::ty::subst::{GenericArg, InternalSubsts}; use rustc_middle::ty::subst::{GenericArg, InternalSubsts};
use rustc_middle::ty::{self, AssocItem, AssocItemContainer, Instance, TyCtxt}; use rustc_middle::ty::{self, Instance, TyCtxt};
use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION; use rustc_session::lint::builtin::UNCONDITIONAL_RECURSION;
use rustc_span::Span; use rustc_span::Span;
use std::ops::ControlFlow; use std::ops::ControlFlow;
@ -14,11 +14,9 @@ pub(crate) fn check<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
if let DefKind::Fn | DefKind::AssocFn = tcx.def_kind(def_id) { if let DefKind::Fn | DefKind::AssocFn = tcx.def_kind(def_id) {
// If this is trait/impl method, extract the trait's substs. // If this is trait/impl method, extract the trait's substs.
let trait_substs = match tcx.opt_associated_item(def_id.to_def_id()) { let trait_substs = match tcx.trait_of_item(def_id.to_def_id()) {
Some(AssocItem { Some(trait_def_id) => {
container: AssocItemContainer::TraitContainer(trait_def_id), .. let trait_substs_count = tcx.generics_of(trait_def_id).count();
}) => {
let trait_substs_count = tcx.generics_of(*trait_def_id).count();
&InternalSubsts::identity_for_item(tcx, def_id.to_def_id())[..trait_substs_count] &InternalSubsts::identity_for_item(tcx, def_id.to_def_id())[..trait_substs_count]
} }
_ => &[], _ => &[],

View File

@ -97,7 +97,7 @@ impl<'tcx> CheckConstVisitor<'tcx> {
// If the function belongs to a trait, then it must enable the const_trait_impl // If the function belongs to a trait, then it must enable the const_trait_impl
// feature to use that trait function (with a const default body). // feature to use that trait function (with a const default body).
if tcx.trait_of_item(def_id).is_some() { if tcx.trait_of_item(def_id.to_def_id()).is_some() {
return true; return true;
} }

View File

@ -212,7 +212,7 @@ where
// `impl Pub<Priv> { pub fn my_method() {} }` is considered a private type, // `impl Pub<Priv> { pub fn my_method() {} }` is considered a private type,
// so we need to visit the self type additionally. // so we need to visit the self type additionally.
if let Some(assoc_item) = tcx.opt_associated_item(def_id) { if let Some(assoc_item) = tcx.opt_associated_item(def_id) {
if let ty::ImplContainer(impl_def_id) = assoc_item.container { if let Some(impl_def_id) = assoc_item.impl_container(tcx) {
tcx.type_of(impl_def_id).visit_with(self)?; tcx.type_of(impl_def_id).visit_with(self)?;
} }
} }
@ -734,11 +734,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
self.reach(item.def_id, item_level).generics().predicates(); self.reach(item.def_id, item_level).generics().predicates();
for trait_item_ref in trait_item_refs { for trait_item_ref in trait_item_refs {
let tcx = self.tcx;
let mut reach = self.reach(trait_item_ref.id.def_id, item_level); let mut reach = self.reach(trait_item_ref.id.def_id, item_level);
reach.generics().predicates(); reach.generics().predicates();
if trait_item_ref.kind == AssocItemKind::Type if trait_item_ref.kind == AssocItemKind::Type
&& !trait_item_ref.defaultness.has_value() && !tcx.impl_defaultness(trait_item_ref.id.def_id).has_value()
{ {
// No type to visit. // No type to visit.
} else { } else {
@ -1839,14 +1840,13 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
&self, &self,
def_id: LocalDefId, def_id: LocalDefId,
assoc_item_kind: AssocItemKind, assoc_item_kind: AssocItemKind,
defaultness: hir::Defaultness,
vis: ty::Visibility, vis: ty::Visibility,
) { ) {
let mut check = self.check(def_id, vis); let mut check = self.check(def_id, vis);
let (check_ty, is_assoc_ty) = match assoc_item_kind { let (check_ty, is_assoc_ty) = match assoc_item_kind {
AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false), AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
AssocItemKind::Type => (defaultness.has_value(), true), AssocItemKind::Type => (self.tcx.impl_defaultness(def_id).has_value(), true),
}; };
check.in_assoc_ty = is_assoc_ty; check.in_assoc_ty = is_assoc_ty;
check.generics().predicates(); check.generics().predicates();
@ -1878,7 +1878,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
self.check_assoc_item( self.check_assoc_item(
trait_item_ref.id.def_id, trait_item_ref.id.def_id,
trait_item_ref.kind, trait_item_ref.kind,
trait_item_ref.defaultness,
item_visibility, item_visibility,
); );
@ -1951,7 +1950,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
self.check_assoc_item( self.check_assoc_item(
impl_item_ref.id.def_id, impl_item_ref.id.def_id,
impl_item_ref.kind, impl_item_ref.kind,
impl_item_ref.defaultness,
impl_item_vis, impl_item_vis,
); );
} }

View File

@ -564,8 +564,8 @@ impl<'tcx> SaveContext<'tcx> {
return None; return None;
}; };
let (def_id, decl_id) = match self.tcx.associated_item(method_id).container { let (def_id, decl_id) = match self.tcx.associated_item(method_id).container {
ty::ImplContainer(_) => (Some(method_id), None), ty::ImplContainer => (Some(method_id), None),
ty::TraitContainer(_) => (None, Some(method_id)), ty::TraitContainer => (None, Some(method_id)),
}; };
let sub_span = seg.ident.span; let sub_span = seg.ident.span;
filter!(self.span_utils, sub_span); filter!(self.span_utils, sub_span);
@ -697,7 +697,7 @@ impl<'tcx> SaveContext<'tcx> {
} }
Res::Def(HirDefKind::AssocFn, decl_id) => { Res::Def(HirDefKind::AssocFn, decl_id) => {
let def_id = if decl_id.is_local() { let def_id = if decl_id.is_local() {
if self.tcx.associated_item(decl_id).defaultness.has_value() { if self.tcx.impl_defaultness(decl_id).has_value() {
Some(decl_id) Some(decl_id)
} else { } else {
None None

View File

@ -2129,7 +2129,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
} }
] = path.segments ] = path.segments
&& data.trait_ref.def_id == *trait_id && data.trait_ref.def_id == *trait_id
&& self.tcx.trait_of_item(item_id) == Some(*trait_id) && self.tcx.trait_of_item(*item_id) == Some(*trait_id)
&& !self.is_tainted_by_errors() && !self.is_tainted_by_errors()
{ {
let (verb, noun) = match self.tcx.associated_item(item_id).kind { let (verb, noun) = match self.tcx.associated_item(item_id).kind {

View File

@ -2714,7 +2714,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if let Some(ident) = self if let Some(ident) = self
.tcx .tcx
.opt_associated_item(trait_item_def_id) .opt_associated_item(trait_item_def_id)
.and_then(|i| self.tcx.opt_item_ident(i.container.id())) .and_then(|i| self.tcx.opt_item_ident(i.container_id(self.tcx)))
{ {
assoc_span.push_span_label(ident.span, "in this trait"); assoc_span.push_span_label(ident.span, "in this trait");
} }

View File

@ -690,7 +690,7 @@ fn receiver_is_dispatchable<'tcx>(
// U: Trait<Arg1, ..., ArgN> // U: Trait<Arg1, ..., ArgN>
let trait_predicate = { let trait_predicate = {
let substs = let substs =
InternalSubsts::for_item(tcx, method.container.assert_trait(), |param, _| { InternalSubsts::for_item(tcx, method.trait_container(tcx).unwrap(), |param, _| {
if param.index == 0 { if param.index == 0 {
unsized_self_ty.into() unsized_self_ty.into()
} else { } else {

View File

@ -1988,7 +1988,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
return Progress { term: tcx.ty_error().into(), obligations: nested }; return Progress { term: tcx.ty_error().into(), obligations: nested };
}; };
if !assoc_ty.item.defaultness.has_value() { if !assoc_ty.item.defaultness(tcx).has_value() {
// This means that the impl is missing a definition for the // This means that the impl is missing a definition for the
// associated type. This error will be reported by the type // associated type. This error will be reported by the type
// checker method `check_impl_items_against_trait`, so here we // checker method `check_impl_items_against_trait`, so here we
@ -2089,7 +2089,11 @@ fn assoc_def(
return Ok(specialization_graph::LeafDef { return Ok(specialization_graph::LeafDef {
item: *item, item: *item,
defining_node: impl_node, defining_node: impl_node,
finalizing_node: if item.defaultness.is_default() { None } else { Some(impl_node) }, finalizing_node: if item.defaultness(tcx).is_default() {
None
} else {
Some(impl_node)
},
}); });
} }

View File

@ -358,7 +358,8 @@ pub fn generator_trait_ref_and_outputs<'tcx>(
} }
pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool { pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
assoc_item.defaultness.is_final() && tcx.impl_defaultness(assoc_item.container.id()).is_final() assoc_item.defaultness(tcx).is_final()
&& tcx.impl_defaultness(assoc_item.container_id(tcx)).is_final()
} }
pub enum TupleArgumentsFlag { pub enum TupleArgumentsFlag {

View File

@ -8,9 +8,7 @@
use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::traits::ChalkRustInterner as RustInterner;
use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef};
use rustc_middle::ty::{ use rustc_middle::ty::{self, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
self, AssocItemContainer, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable,
};
use rustc_ast::ast; use rustc_ast::ast;
use rustc_attr as attr; use rustc_attr as attr;
@ -74,7 +72,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
) -> Arc<chalk_solve::rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> { ) -> Arc<chalk_solve::rust_ir::AssociatedTyDatum<RustInterner<'tcx>>> {
let def_id = assoc_type_id.0; let def_id = assoc_type_id.0;
let assoc_item = self.interner.tcx.associated_item(def_id); let assoc_item = self.interner.tcx.associated_item(def_id);
let AssocItemContainer::TraitContainer(trait_def_id) = assoc_item.container else { let Some(trait_def_id) = assoc_item.trait_container(self.interner.tcx) else {
unimplemented!("Not possible??"); unimplemented!("Not possible??");
}; };
match assoc_item.kind { match assoc_item.kind {
@ -455,7 +453,7 @@ impl<'tcx> chalk_solve::RustIrDatabase<RustInterner<'tcx>> for RustIrDatabase<'t
) -> Arc<chalk_solve::rust_ir::AssociatedTyValue<RustInterner<'tcx>>> { ) -> Arc<chalk_solve::rust_ir::AssociatedTyValue<RustInterner<'tcx>>> {
let def_id = associated_ty_id.0; let def_id = associated_ty_id.0;
let assoc_item = self.interner.tcx.associated_item(def_id); let assoc_item = self.interner.tcx.associated_item(def_id);
let impl_id = assoc_item.container.id(); let impl_id = assoc_item.container_id(self.interner.tcx);
match assoc_item.kind { match assoc_item.kind {
AssocKind::Type => {} AssocKind::Type => {}
_ => unimplemented!("Not possible??"), _ => unimplemented!("Not possible??"),

View File

@ -1,6 +1,6 @@
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::DefId;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
pub fn provide(providers: &mut ty::query::Providers) { pub fn provide(providers: &mut ty::query::Providers) {
@ -9,7 +9,6 @@ pub fn provide(providers: &mut ty::query::Providers) {
associated_item_def_ids, associated_item_def_ids,
associated_items, associated_items,
impl_item_implementor_ids, impl_item_implementor_ids,
trait_of_item,
..*providers ..*providers
}; };
} }
@ -40,16 +39,6 @@ fn impl_item_implementor_ids(tcx: TyCtxt<'_>, impl_id: DefId) -> FxHashMap<DefId
.collect() .collect()
} }
/// If the given `DefId` describes an item belonging to a trait,
/// returns the `DefId` of the trait that the trait item belongs to;
/// otherwise, returns `None`.
fn trait_of_item(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
tcx.opt_associated_item(def_id).and_then(|associated_item| match associated_item.container {
ty::TraitContainer(def_id) => Some(def_id),
ty::ImplContainer(_) => None,
})
}
fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem { fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
let id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); let id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());
let parent_def_id = tcx.hir().get_parent_item(id); let parent_def_id = tcx.hir().get_parent_item(id);
@ -59,8 +48,7 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
if let Some(impl_item_ref) = if let Some(impl_item_ref) =
impl_.items.iter().find(|i| i.id.def_id.to_def_id() == def_id) impl_.items.iter().find(|i| i.id.def_id.to_def_id() == def_id)
{ {
let assoc_item = let assoc_item = associated_item_from_impl_item_ref(impl_item_ref);
associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref);
debug_assert_eq!(assoc_item.def_id, def_id); debug_assert_eq!(assoc_item.def_id, def_id);
return assoc_item; return assoc_item;
} }
@ -70,8 +58,7 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
if let Some(trait_item_ref) = if let Some(trait_item_ref) =
trait_item_refs.iter().find(|i| i.id.def_id.to_def_id() == def_id) trait_item_refs.iter().find(|i| i.id.def_id.to_def_id() == def_id)
{ {
let assoc_item = let assoc_item = associated_item_from_trait_item_ref(trait_item_ref);
associated_item_from_trait_item_ref(tcx, parent_def_id, trait_item_ref);
debug_assert_eq!(assoc_item.def_id, def_id); debug_assert_eq!(assoc_item.def_id, def_id);
return assoc_item; return assoc_item;
} }
@ -87,11 +74,7 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem {
) )
} }
fn associated_item_from_trait_item_ref( fn associated_item_from_trait_item_ref(trait_item_ref: &hir::TraitItemRef) -> ty::AssocItem {
tcx: TyCtxt<'_>,
parent_def_id: LocalDefId,
trait_item_ref: &hir::TraitItemRef,
) -> ty::AssocItem {
let def_id = trait_item_ref.id.def_id; let def_id = trait_item_ref.id.def_id;
let (kind, has_self) = match trait_item_ref.kind { let (kind, has_self) = match trait_item_ref.kind {
hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
@ -102,20 +85,14 @@ fn associated_item_from_trait_item_ref(
ty::AssocItem { ty::AssocItem {
name: trait_item_ref.ident.name, name: trait_item_ref.ident.name,
kind, kind,
vis: tcx.visibility(def_id),
defaultness: trait_item_ref.defaultness,
def_id: def_id.to_def_id(), def_id: def_id.to_def_id(),
trait_item_def_id: Some(def_id.to_def_id()), trait_item_def_id: Some(def_id.to_def_id()),
container: ty::TraitContainer(parent_def_id.to_def_id()), container: ty::TraitContainer,
fn_has_self_parameter: has_self, fn_has_self_parameter: has_self,
} }
} }
fn associated_item_from_impl_item_ref( fn associated_item_from_impl_item_ref(impl_item_ref: &hir::ImplItemRef) -> ty::AssocItem {
tcx: TyCtxt<'_>,
parent_def_id: LocalDefId,
impl_item_ref: &hir::ImplItemRef,
) -> ty::AssocItem {
let def_id = impl_item_ref.id.def_id; let def_id = impl_item_ref.id.def_id;
let (kind, has_self) = match impl_item_ref.kind { let (kind, has_self) = match impl_item_ref.kind {
hir::AssocItemKind::Const => (ty::AssocKind::Const, false), hir::AssocItemKind::Const => (ty::AssocKind::Const, false),
@ -126,11 +103,9 @@ fn associated_item_from_impl_item_ref(
ty::AssocItem { ty::AssocItem {
name: impl_item_ref.ident.name, name: impl_item_ref.ident.name,
kind, kind,
vis: tcx.visibility(def_id),
defaultness: impl_item_ref.defaultness,
def_id: def_id.to_def_id(), def_id: def_id.to_def_id(),
trait_item_def_id: impl_item_ref.trait_item_def_id, trait_item_def_id: impl_item_ref.trait_item_def_id,
container: ty::ImplContainer(parent_def_id.to_def_id()), container: ty::ImplContainer,
fn_has_self_parameter: has_self, fn_has_self_parameter: has_self,
} }
} }

View File

@ -281,7 +281,7 @@ fn resolve_associated_item<'tcx>(
} }
// If the item does not have a value, then we cannot return an instance. // If the item does not have a value, then we cannot return an instance.
if !leaf_def.item.defaultness.has_value() { if !leaf_def.item.defaultness(tcx).has_value() {
return Ok(None); return Ok(None);
} }

View File

@ -70,11 +70,13 @@ fn sized_constraint_for_ty<'tcx>(
} }
fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness { fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness {
let item = tcx.hir().expect_item(def_id.expect_local()); match tcx.hir().get_by_def_id(def_id.expect_local()) {
if let hir::ItemKind::Impl(impl_) = &item.kind { hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.defaultness,
impl_.defaultness hir::Node::ImplItem(hir::ImplItem { defaultness, .. })
} else { | hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness,
bug!("`impl_defaultness` called on {:?}", item); node => {
bug!("`impl_defaultness` called on {:?}", node);
}
} }
} }

View File

@ -255,7 +255,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
trait_bound_spans.push(*span); trait_bound_spans.push(*span);
} }
for assoc_item in items { for assoc_item in items {
let trait_def_id = assoc_item.container.id(); let trait_def_id = assoc_item.container_id(tcx);
names.push(format!( names.push(format!(
"`{}` (from trait `{}`)", "`{}` (from trait `{}`)",
assoc_item.name, assoc_item.name,
@ -321,7 +321,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let mut dupes = false; let mut dupes = false;
for item in assoc_items { for item in assoc_items {
let prefix = if names[&item.name] > 1 { let prefix = if names[&item.name] > 1 {
let trait_def_id = item.container.id(); let trait_def_id = item.container_id(tcx);
dupes = true; dupes = true;
format!("{}::", tcx.def_path_str(trait_def_id)) format!("{}::", tcx.def_path_str(trait_def_id))
} else { } else {
@ -376,7 +376,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let mut label = vec![]; let mut label = vec![];
for item in assoc_items { for item in assoc_items {
let postfix = if names[&item.name] > 1 { let postfix = if names[&item.name] > 1 {
let trait_def_id = item.container.id(); let trait_def_id = item.container_id(tcx);
format!(" (from trait `{}`)", tcx.def_path_str(trait_def_id)) format!(" (from trait `{}`)", tcx.def_path_str(trait_def_id))
} else { } else {
String::new() String::new()

View File

@ -1141,7 +1141,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
.or_else(|| find_item_of_kind(ty::AssocKind::Const)) .or_else(|| find_item_of_kind(ty::AssocKind::Const))
.expect("missing associated type"); .expect("missing associated type");
if !assoc_item.vis.is_accessible_from(def_scope, tcx) { if !assoc_item.visibility(tcx).is_accessible_from(def_scope, tcx) {
tcx.sess tcx.sess
.struct_span_err( .struct_span_err(
binding.span, binding.span,
@ -1160,7 +1160,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
span: binding.span, span: binding.span,
prev_span: *prev_span, prev_span: *prev_span,
item_name: binding.item_name, item_name: binding.item_name,
def_path: tcx.def_path_str(assoc_item.container.id()), def_path: tcx.def_path_str(assoc_item.container_id(tcx)),
}); });
}) })
.or_insert(binding.span); .or_insert(binding.span);
@ -1997,7 +1997,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let ty = self.normalize_ty(span, ty); let ty = self.normalize_ty(span, ty);
let kind = DefKind::AssocTy; let kind = DefKind::AssocTy;
if !item.vis.is_accessible_from(def_scope, tcx) { if !item.visibility(tcx).is_accessible_from(def_scope, tcx) {
let kind = kind.descr(item.def_id); let kind = kind.descr(item.def_id);
let msg = format!("{} `{}` is private", kind, assoc_ident); let msg = format!("{} `{}` is private", kind, assoc_ident);
tcx.sess tcx.sess

View File

@ -1098,7 +1098,7 @@ fn check_impl_items_against_trait<'tcx>(
for &trait_item_id in tcx.associated_item_def_ids(impl_trait_ref.def_id) { for &trait_item_id in tcx.associated_item_def_ids(impl_trait_ref.def_id) {
let is_implemented = ancestors let is_implemented = ancestors
.leaf_def(tcx, trait_item_id) .leaf_def(tcx, trait_item_id)
.map_or(false, |node_item| node_item.item.defaultness.has_value()); .map_or(false, |node_item| node_item.item.defaultness(tcx).has_value());
if !is_implemented && tcx.impl_defaultness(impl_id).is_final() { if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
missing_items.push(tcx.associated_item(trait_item_id)); missing_items.push(tcx.associated_item(trait_item_id));

View File

@ -165,7 +165,7 @@ fn compare_predicate_entailment<'tcx>(
// Create mapping from trait to placeholder. // Create mapping from trait to placeholder.
let trait_to_placeholder_substs = let trait_to_placeholder_substs =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs); impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_substs);
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs); debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
let impl_m_generics = tcx.generics_of(impl_m.def_id); let impl_m_generics = tcx.generics_of(impl_m.def_id);
@ -511,8 +511,8 @@ fn compare_self_type<'tcx>(
let self_string = |method: &ty::AssocItem| { let self_string = |method: &ty::AssocItem| {
let untransformed_self_ty = match method.container { let untransformed_self_ty = match method.container {
ty::ImplContainer(_) => impl_trait_ref.self_ty(), ty::ImplContainer => impl_trait_ref.self_ty(),
ty::TraitContainer(_) => tcx.types.self_param, ty::TraitContainer => tcx.types.self_param,
}; };
let self_arg_ty = tcx.fn_sig(method.def_id).input(0); let self_arg_ty = tcx.fn_sig(method.def_id).input(0);
let param_env = ty::ParamEnv::reveal_all(); let param_env = ty::ParamEnv::reveal_all();
@ -1194,7 +1194,7 @@ fn compare_type_predicate_entailment<'tcx>(
) -> Result<(), ErrorGuaranteed> { ) -> Result<(), ErrorGuaranteed> {
let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id); let impl_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
let trait_to_impl_substs = let trait_to_impl_substs =
impl_substs.rebase_onto(tcx, impl_ty.container.id(), impl_trait_ref.substs); impl_substs.rebase_onto(tcx, impl_ty.container_id(tcx), impl_trait_ref.substs);
let impl_ty_generics = tcx.generics_of(impl_ty.def_id); let impl_ty_generics = tcx.generics_of(impl_ty.def_id);
let trait_ty_generics = tcx.generics_of(trait_ty.def_id); let trait_ty_generics = tcx.generics_of(trait_ty.def_id);
@ -1390,9 +1390,9 @@ pub fn check_type_bounds<'tcx>(
}); });
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter()); let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
let impl_ty_substs = tcx.intern_substs(&substs); let impl_ty_substs = tcx.intern_substs(&substs);
let container_id = impl_ty.container_id(tcx);
let rebased_substs = let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
impl_ty_substs.rebase_onto(tcx, impl_ty.container.id(), impl_trait_ref.substs);
let impl_ty_value = tcx.type_of(impl_ty.def_id); let impl_ty_value = tcx.type_of(impl_ty.def_id);
let param_env = tcx.param_env(impl_ty.def_id); let param_env = tcx.param_env(impl_ty.def_id);
@ -1441,8 +1441,7 @@ pub fn check_type_bounds<'tcx>(
debug!(?normalize_param_env); debug!(?normalize_param_env);
let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id); let impl_ty_substs = InternalSubsts::identity_for_item(tcx, impl_ty.def_id);
let rebased_substs = let rebased_substs = impl_ty_substs.rebase_onto(tcx, container_id, impl_trait_ref.substs);
impl_ty_substs.rebase_onto(tcx, impl_ty.container.id(), impl_trait_ref.substs);
tcx.infer_ctxt().enter(move |infcx| { tcx.infer_ctxt().enter(move |infcx| {
let ocx = ObligationCtxt::new(&infcx); let ocx = ObligationCtxt::new(&infcx);
@ -1505,10 +1504,13 @@ pub fn check_type_bounds<'tcx>(
// Finally, resolve all regions. This catches wily misuses of // Finally, resolve all regions. This catches wily misuses of
// lifetime parameters. // lifetime parameters.
let implied_bounds = match impl_ty.container { let implied_bounds = match impl_ty.container {
ty::TraitContainer(_) => FxHashSet::default(), ty::TraitContainer => FxHashSet::default(),
ty::ImplContainer(def_id) => { ty::ImplContainer => wfcheck::impl_implied_bounds(
wfcheck::impl_implied_bounds(tcx, param_env, def_id.expect_local(), impl_ty_span) tcx,
} param_env,
container_id.expect_local(),
impl_ty_span,
),
}; };
let mut outlives_environment = OutlivesEnvironment::new(param_env); let mut outlives_environment = OutlivesEnvironment::new(param_env);
outlives_environment.add_implied_bounds(&infcx, implied_bounds, impl_ty_hir_id); outlives_environment.add_implied_bounds(&infcx, implied_bounds, impl_ty_hir_id);

View File

@ -775,7 +775,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map( self.typeck_results.borrow().type_dependent_def_id(expr.hir_id).map(
|did| { |did| {
let ai = self.tcx.associated_item(did); let ai = self.tcx.associated_item(did);
ai.container == ty::TraitContainer(clone_trait) ai.trait_container(self.tcx) == Some(clone_trait)
}, },
), ),
segment.ident.name, segment.ident.name,

View File

@ -1090,13 +1090,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
is_alias_variant_ctor = true; is_alias_variant_ctor = true;
} }
Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => { Res::Def(DefKind::AssocFn | DefKind::AssocConst, def_id) => {
let container = tcx.associated_item(def_id).container; let assoc_item = tcx.associated_item(def_id);
debug!(?def_id, ?container); let container = assoc_item.container;
let container_id = assoc_item.container_id(tcx);
debug!(?def_id, ?container, ?container_id);
match container { match container {
ty::TraitContainer(trait_did) => { ty::TraitContainer => {
callee::check_legal_trait_for_method_call(tcx, span, None, span, trait_did) callee::check_legal_trait_for_method_call(tcx, span, None, span, container_id)
} }
ty::ImplContainer(impl_def_id) => { ty::ImplContainer => {
if segments.len() == 1 { if segments.len() == 1 {
// `<T>::assoc` will end up here, and so // `<T>::assoc` will end up here, and so
// can `T::assoc`. It this came from an // can `T::assoc`. It this came from an
@ -1104,7 +1106,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// `T` for posterity (see `UserSelfTy` for // `T` for posterity (see `UserSelfTy` for
// details). // details).
let self_ty = self_ty.expect("UFCS sugared assoc missing Self"); let self_ty = self_ty.expect("UFCS sugared assoc missing Self");
user_self_ty = Some(UserSelfTy { impl_def_id, self_ty }); user_self_ty = Some(UserSelfTy { impl_def_id: container_id, self_ty });
} }
} }
} }

View File

@ -839,8 +839,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& results.type_dependent_def_id(expr.hir_id).map_or( && results.type_dependent_def_id(expr.hir_id).map_or(
false, false,
|did| { |did| {
self.tcx.associated_item(did).container let assoc_item = self.tcx.associated_item(did);
== ty::AssocItemContainer::TraitContainer(clone_trait_did) assoc_item.container == ty::AssocItemContainer::TraitContainer
&& assoc_item.container_id(self.tcx) == clone_trait_did
}, },
) )
// If that clone call hasn't already dereferenced the self type (i.e. don't give this // If that clone call hasn't already dereferenced the self type (i.e. don't give this

View File

@ -238,7 +238,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
) -> SubstsRef<'tcx> { ) -> SubstsRef<'tcx> {
match pick.kind { match pick.kind {
probe::InherentImplPick => { probe::InherentImplPick => {
let impl_def_id = pick.item.container.id(); let impl_def_id = pick.item.container_id(self.tcx);
assert!( assert!(
self.tcx.impl_trait_ref(impl_def_id).is_none(), self.tcx.impl_trait_ref(impl_def_id).is_none(),
"impl {:?} is not an inherent impl", "impl {:?} is not an inherent impl",
@ -248,7 +248,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
} }
probe::ObjectPick => { probe::ObjectPick => {
let trait_def_id = pick.item.container.id(); let trait_def_id = pick.item.container_id(self.tcx);
self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| { self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| {
// The object data has no entry for the Self // The object data has no entry for the Self
// Type. For the purposes of this method call, we // Type. For the purposes of this method call, we
@ -273,7 +273,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
} }
probe::TraitPick => { probe::TraitPick => {
let trait_def_id = pick.item.container.id(); let trait_def_id = pick.item.container_id(self.tcx);
// Make a trait reference `$0 : Trait<$1...$n>` // Make a trait reference `$0 : Trait<$1...$n>`
// consisting entirely of type variables. Later on in // consisting entirely of type variables. Later on in
@ -540,15 +540,14 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) { fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) {
// Disallow calls to the method `drop` defined in the `Drop` trait. // Disallow calls to the method `drop` defined in the `Drop` trait.
match pick.item.container { if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
ty::TraitContainer(trait_def_id) => callee::check_legal_trait_for_method_call( callee::check_legal_trait_for_method_call(
self.tcx, self.tcx,
self.span, self.span,
Some(self.self_expr.span), Some(self.self_expr.span),
self.call_expr.span, self.call_expr.span,
trait_def_id, trait_def_id,
), )
ty::ImplContainer(..) => {}
} }
} }

View File

@ -231,7 +231,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ProbeScope::AllTraits, ProbeScope::AllTraits,
) { ) {
// If we find a different result the caller probably forgot to import a trait. // If we find a different result the caller probably forgot to import a trait.
Ok(ref new_pick) if *new_pick != pick => vec![new_pick.item.container.id()], Ok(ref new_pick) if *new_pick != pick => vec![new_pick.item.container_id(self.tcx)],
Err(Ambiguity(ref sources)) => sources Err(Ambiguity(ref sources)) => sources
.iter() .iter()
.filter_map(|source| { .filter_map(|source| {

View File

@ -148,7 +148,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let trait_name = self.trait_path_or_bare_name( let trait_name = self.trait_path_or_bare_name(
span, span,
call_expr.hir_id, call_expr.hir_id,
pick.item.container.id(), pick.item.container_id(self.tcx),
); );
let mut lint = lint.build(&format!( let mut lint = lint.build(&format!(
@ -261,8 +261,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| { self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
// "type" refers to either a type or, more likely, a trait from which // "type" refers to either a type or, more likely, a trait from which
// the associated function or method is from. // the associated function or method is from.
let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id()); let container_id = pick.item.container_id(self.tcx);
let trait_generics = self.tcx.generics_of(pick.item.container.id()); let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
let trait_generics = self.tcx.generics_of(container_id);
let trait_name = let trait_name =
if trait_generics.params.len() <= trait_generics.has_self as usize { if trait_generics.params.len() <= trait_generics.has_self as usize {

View File

@ -592,9 +592,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
fn push_candidate(&mut self, candidate: Candidate<'tcx>, is_inherent: bool) { fn push_candidate(&mut self, candidate: Candidate<'tcx>, is_inherent: bool) {
let is_accessible = if let Some(name) = self.method_name { let is_accessible = if let Some(name) = self.method_name {
let item = candidate.item; let item = candidate.item;
let def_scope = let def_scope = self
self.tcx.adjust_ident_and_get_scope(name, item.container.id(), self.body_id).1; .tcx
item.vis.is_accessible_from(def_scope, self.tcx) .adjust_ident_and_get_scope(name, item.container_id(self.tcx), self.body_id)
.1;
item.visibility(self.tcx).is_accessible_from(def_scope, self.tcx)
} else { } else {
true true
}; };
@ -1025,7 +1027,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.assemble_extension_candidates_for_all_traits(); self.assemble_extension_candidates_for_all_traits();
let out_of_scope_traits = match self.pick_core() { let out_of_scope_traits = match self.pick_core() {
Some(Ok(p)) => vec![p.item.container.id()], Some(Ok(p)) => vec![p.item.container_id(self.tcx)],
//Some(Ok(p)) => p.iter().map(|p| p.item.container().id()).collect(), //Some(Ok(p)) => p.iter().map(|p| p.item.container().id()).collect(),
Some(Err(MethodError::Ambiguity(v))) => v Some(Err(MethodError::Ambiguity(v))) => v
.into_iter() .into_iter()
@ -1387,7 +1389,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.tcx.def_path_str(stable_pick.item.def_id), self.tcx.def_path_str(stable_pick.item.def_id),
)); ));
} }
(ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer(def_id)) => { (ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
let def_id = stable_pick.item.container_id(self.tcx);
diag.span_suggestion( diag.span_suggestion(
self.span, self.span,
"use the fully qualified path to the associated const", "use the fully qualified path to the associated const",
@ -1429,9 +1432,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource { fn candidate_source(&self, candidate: &Candidate<'tcx>, self_ty: Ty<'tcx>) -> CandidateSource {
match candidate.kind { match candidate.kind {
InherentImplCandidate(..) => CandidateSource::Impl(candidate.item.container.id()), InherentImplCandidate(..) => {
CandidateSource::Impl(candidate.item.container_id(self.tcx))
}
ObjectCandidate | WhereClauseCandidate(_) => { ObjectCandidate | WhereClauseCandidate(_) => {
CandidateSource::Trait(candidate.item.container.id()) CandidateSource::Trait(candidate.item.container_id(self.tcx))
} }
TraitCandidate(trait_ref) => self.probe(|_| { TraitCandidate(trait_ref) => self.probe(|_| {
let _ = self let _ = self
@ -1444,7 +1449,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// to that impl. // to that impl.
CandidateSource::Impl(impl_data.impl_def_id) CandidateSource::Impl(impl_data.impl_def_id)
} }
_ => CandidateSource::Trait(candidate.item.container.id()), _ => CandidateSource::Trait(candidate.item.container_id(self.tcx)),
} }
}), }),
} }
@ -1502,7 +1507,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty); debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
// Check whether the impl imposes obligations we have to worry about. // Check whether the impl imposes obligations we have to worry about.
let impl_def_id = probe.item.container.id(); let impl_def_id = probe.item.container_id(self.tcx);
let impl_bounds = self.tcx.predicates_of(impl_def_id); let impl_bounds = self.tcx.predicates_of(impl_def_id);
let impl_bounds = impl_bounds.instantiate(self.tcx, substs); let impl_bounds = impl_bounds.instantiate(self.tcx, substs);
let traits::Normalized { value: impl_bounds, obligations: norm_obligations } = let traits::Normalized { value: impl_bounds, obligations: norm_obligations } =
@ -1653,12 +1658,12 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
probes: &[(&Candidate<'tcx>, ProbeResult)], probes: &[(&Candidate<'tcx>, ProbeResult)],
) -> Option<Pick<'tcx>> { ) -> Option<Pick<'tcx>> {
// Do all probes correspond to the same trait? // Do all probes correspond to the same trait?
let container = probes[0].0.item.container; let container = probes[0].0.item.trait_container(self.tcx)?;
if let ty::ImplContainer(_) = container { for (p, _) in &probes[1..] {
return None; let p_container = p.item.trait_container(self.tcx)?;
} if p_container != container {
if probes[1..].iter().any(|&(p, _)| p.item.container != container) { return None;
return None; }
} }
// FIXME: check the return type here somehow. // FIXME: check the return type here somehow.

View File

@ -1789,7 +1789,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// We point at the method, but we just skip the rest of the check for arbitrary // We point at the method, but we just skip the rest of the check for arbitrary
// self types and rely on the suggestion to `use` the trait from // self types and rely on the suggestion to `use` the trait from
// `suggest_valid_traits`. // `suggest_valid_traits`.
let did = Some(pick.item.container.id()); let did = Some(pick.item.container_id(self.tcx));
let skip = skippable.contains(&did); let skip = skippable.contains(&did);
if pick.autoderefs == 0 && !skip { if pick.autoderefs == 0 && !skip {
err.span_label( err.span_label(
@ -1825,7 +1825,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
) )
{ {
debug!("try_alt_rcvr: pick candidate {:?}", pick); debug!("try_alt_rcvr: pick candidate {:?}", pick);
let did = Some(pick.item.container.id()); let did = Some(pick.item.container_id(self.tcx));
// We don't want to suggest a container type when the missing // We don't want to suggest a container type when the missing
// method is `.clone()` or `.deref()` otherwise we'd suggest // method is `.clone()` or `.deref()` otherwise we'd suggest
// `Arc::new(foo).clone()`, which is far from what the user wants. // `Arc::new(foo).clone()`, which is far from what the user wants.
@ -1937,7 +1937,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
// We only want to suggest public or local traits (#45781). // We only want to suggest public or local traits (#45781).
item.vis.is_public() || info.def_id.is_local() item.visibility(self.tcx).is_public() || info.def_id.is_local()
}) })
.is_some() .is_some()
}) })

View File

@ -977,11 +977,14 @@ fn check_associated_item(
let item = tcx.associated_item(item_id); let item = tcx.associated_item(item_id);
let (mut implied_bounds, self_ty) = match item.container { let (mut implied_bounds, self_ty) = match item.container {
ty::TraitContainer(_) => (FxHashSet::default(), tcx.types.self_param), ty::TraitContainer => (FxHashSet::default(), tcx.types.self_param),
ty::ImplContainer(def_id) => ( ty::ImplContainer => {
impl_implied_bounds(tcx, wfcx.param_env, def_id.expect_local(), span), let def_id = item.container_id(tcx);
tcx.type_of(def_id), (
), impl_implied_bounds(tcx, wfcx.param_env, def_id.expect_local(), span),
tcx.type_of(def_id),
)
}
}; };
match item.kind { match item.kind {
@ -1004,10 +1007,10 @@ fn check_associated_item(
check_method_receiver(wfcx, hir_sig, item, self_ty); check_method_receiver(wfcx, hir_sig, item, self_ty);
} }
ty::AssocKind::Type => { ty::AssocKind::Type => {
if let ty::AssocItemContainer::TraitContainer(_) = item.container { if let ty::AssocItemContainer::TraitContainer = item.container {
check_associated_type_bounds(wfcx, item, span) check_associated_type_bounds(wfcx, item, span)
} }
if item.defaultness.has_value() { if item.defaultness(tcx).has_value() {
let ty = tcx.type_of(item.def_id); let ty = tcx.type_of(item.def_id);
let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
wfcx.register_wf_obligation(span, loc, ty.into()); wfcx.register_wf_obligation(span, loc, ty.into());

View File

@ -1234,7 +1234,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
match item { match item {
Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => { Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
if !item.defaultness.has_value() { if !tcx.impl_defaultness(item.id.def_id).has_value() {
tcx.sess tcx.sess
.struct_span_err( .struct_span_err(
item.span, item.span,
@ -2433,7 +2433,7 @@ fn explicit_predicates_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::Generic
// supertrait). // supertrait).
if let ty::Projection(projection) = ty.kind() { if let ty::Projection(projection) = ty.kind() {
projection.substs == trait_identity_substs projection.substs == trait_identity_substs
&& tcx.associated_item(projection.item_def_id).container.id() == def_id && tcx.associated_item(projection.item_def_id).container_id(tcx) == def_id
} else { } else {
false false
} }
@ -3264,7 +3264,7 @@ fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx FxHashSet<S
/// applied to the method prototype. /// applied to the method prototype.
fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool { fn should_inherit_track_caller(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
if let Some(impl_item) = tcx.opt_associated_item(def_id) if let Some(impl_item) = tcx.opt_associated_item(def_id)
&& let ty::AssocItemContainer::ImplContainer(_) = impl_item.container && let ty::AssocItemContainer::ImplContainer = impl_item.container
&& let Some(trait_item) = impl_item.trait_item_def_id && let Some(trait_item) = impl_item.trait_item_def_id
{ {
return tcx return tcx

View File

@ -3,7 +3,7 @@ use crate::astconv::AstConv;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::traits::util; use rustc_infer::traits::util;
use rustc_middle::ty::subst::InternalSubsts; use rustc_middle::ty::subst::InternalSubsts;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, DefIdTree, TyCtxt};
use rustc_span::def_id::DefId; use rustc_span::def_id::DefId;
use rustc_span::Span; use rustc_span::Span;
@ -30,7 +30,7 @@ fn associated_type_bounds<'tcx>(
// Associated types are implicitly sized unless a `?Sized` bound is found // Associated types are implicitly sized unless a `?Sized` bound is found
<dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span); <dyn AstConv<'_>>::add_implicitly_sized(&icx, &mut bounds, ast_bounds, None, span);
let trait_def_id = tcx.associated_item(assoc_item_def_id).container.id(); let trait_def_id = tcx.parent(assoc_item_def_id);
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local()); let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id.expect_local());
let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| { let bounds_from_parent = trait_predicates.predicates.iter().copied().filter(|(pred, _)| {

View File

@ -106,7 +106,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId)
let item = tcx.associated_item(def_id); let item = tcx.associated_item(def_id);
match item.kind { match item.kind {
ty::AssocKind::Type => { ty::AssocKind::Type => {
if item.defaultness.has_value() { if item.defaultness(tcx).has_value() {
cgp::parameters_for(&tcx.type_of(def_id), true) cgp::parameters_for(&tcx.type_of(def_id), true)
} else { } else {
Vec::new() Vec::new()

View File

@ -2,7 +2,7 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst}; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
use rustc_middle::ty::{self, Ty, TyCtxt}; use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
use rustc_span::Span; use rustc_span::Span;
use super::explicit::ExplicitPredicatesMap; use super::explicit::ExplicitPredicatesMap;
@ -202,7 +202,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
debug!("Projection"); debug!("Projection");
check_explicit_predicates( check_explicit_predicates(
tcx, tcx,
tcx.associated_item(obj.item_def_id).container.id(), tcx.parent(obj.item_def_id),
obj.substs, obj.substs,
required_predicates, required_predicates,
explicit_map, explicit_map,

View File

@ -439,7 +439,7 @@ pub(crate) fn build_impl(
.unwrap(); // corresponding associated item has to exist .unwrap(); // corresponding associated item has to exist
!tcx.is_doc_hidden(trait_item.def_id) !tcx.is_doc_hidden(trait_item.def_id)
} else { } else {
item.vis.is_public() item.visibility(tcx).is_public()
} }
}) })
.map(|item| item.clean(cx)) .map(|item| item.clean(cx))

View File

@ -1101,7 +1101,7 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> {
} }
hir::ImplItemKind::Fn(ref sig, body) => { hir::ImplItemKind::Fn(ref sig, body) => {
let m = clean_function(cx, sig, self.generics, body); let m = clean_function(cx, sig, self.generics, body);
let defaultness = cx.tcx.associated_item(self.def_id).defaultness; let defaultness = cx.tcx.impl_defaultness(self.def_id);
MethodItem(m, Some(defaultness)) MethodItem(m, Some(defaultness))
} }
hir::ImplItemKind::TyAlias(hir_ty) => { hir::ImplItemKind::TyAlias(hir_ty) => {
@ -1139,8 +1139,8 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
let ty = clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id)); let ty = clean_middle_ty(tcx.type_of(self.def_id), cx, Some(self.def_id));
let provided = match self.container { let provided = match self.container {
ty::ImplContainer(_) => true, ty::ImplContainer => true,
ty::TraitContainer(_) => self.defaultness.has_value(), ty::TraitContainer => tcx.impl_defaultness(self.def_id).has_value(),
}; };
if provided { if provided {
AssocConstItem(ty, ConstantKind::Extern { def_id: self.def_id }) AssocConstItem(ty, ConstantKind::Extern { def_id: self.def_id })
@ -1159,8 +1159,8 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
if self.fn_has_self_parameter { if self.fn_has_self_parameter {
let self_ty = match self.container { let self_ty = match self.container {
ty::ImplContainer(def_id) => tcx.type_of(def_id), ty::ImplContainer => tcx.type_of(self.container_id(tcx)),
ty::TraitContainer(_) => tcx.types.self_param, ty::TraitContainer => tcx.types.self_param,
}; };
let self_arg_ty = sig.input(0).skip_binder(); let self_arg_ty = sig.input(0).skip_binder();
if self_arg_ty == self_ty { if self_arg_ty == self_ty {
@ -1178,13 +1178,13 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
} }
let provided = match self.container { let provided = match self.container {
ty::ImplContainer(_) => true, ty::ImplContainer => true,
ty::TraitContainer(_) => self.defaultness.has_value(), ty::TraitContainer => self.defaultness(tcx).has_value(),
}; };
if provided { if provided {
let defaultness = match self.container { let defaultness = match self.container {
ty::ImplContainer(_) => Some(self.defaultness), ty::ImplContainer => Some(self.defaultness(tcx)),
ty::TraitContainer(_) => None, ty::TraitContainer => None,
}; };
MethodItem(Box::new(Function { generics, decl }), defaultness) MethodItem(Box::new(Function { generics, decl }), defaultness)
} else { } else {
@ -1215,7 +1215,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
} }
} }
if let ty::TraitContainer(_) = self.container { if let ty::TraitContainer = self.container {
let bounds = tcx.explicit_item_bounds(self.def_id); let bounds = tcx.explicit_item_bounds(self.def_id);
let predicates = ty::GenericPredicates { parent: None, predicates: bounds }; let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
let mut generics = let mut generics =
@ -1232,7 +1232,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
if assoc.name != my_name { if assoc.name != my_name {
return false; return false;
} }
if trait_.def_id() != self.container.id() { if trait_.def_id() != self.container_id(tcx) {
return false; return false;
} }
match **self_type { match **self_type {
@ -1280,7 +1280,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem {
None => bounds.push(GenericBound::maybe_sized(cx)), None => bounds.push(GenericBound::maybe_sized(cx)),
} }
if self.defaultness.has_value() { if tcx.impl_defaultness(self.def_id).has_value() {
AssocTypeItem( AssocTypeItem(
Box::new(Typedef { Box::new(Typedef {
type_: clean_middle_ty( type_: clean_middle_ty(
@ -1356,7 +1356,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type
} }
let trait_segments = &p.segments[..p.segments.len() - 1]; let trait_segments = &p.segments[..p.segments.len() - 1];
let trait_def = cx.tcx.associated_item(p.res.def_id()).container.id(); let trait_def = cx.tcx.associated_item(p.res.def_id()).container_id(cx.tcx);
let trait_ = self::Path { let trait_ = self::Path {
res: Res::Def(DefKind::Trait, trait_def), res: Res::Def(DefKind::Trait, trait_def),
segments: trait_segments.iter().map(|x| x.clean(cx)).collect(), segments: trait_segments.iter().map(|x| x.clean(cx)).collect(),

View File

@ -234,7 +234,7 @@ impl UrlFragment {
&UrlFragment::Item(def_id) => { &UrlFragment::Item(def_id) => {
let kind = match tcx.def_kind(def_id) { let kind = match tcx.def_kind(def_id) {
DefKind::AssocFn => { DefKind::AssocFn => {
if tcx.associated_item(def_id).defaultness.has_value() { if tcx.impl_defaultness(def_id).has_value() {
"method." "method."
} else { } else {
"tymethod." "tymethod."

View File

@ -116,9 +116,9 @@ impl Foo {
// Change Method Privacy ------------------------------------------------------- // Change Method Privacy -------------------------------------------------------
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
impl Foo { impl Foo {
//----------------------------------------------------
//-------------------------- //--------------------------
//------------------------------------------------------------------------------ //--------------------------
//--------------------------------------------------------------
//-------------------------- //--------------------------
pub fn method_privacy() { } pub fn method_privacy() { }
} }
@ -129,9 +129,9 @@ impl Foo {
#[rustc_clean(cfg="cfail5")] #[rustc_clean(cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
impl Foo { impl Foo {
#[rustc_clean(cfg="cfail2", except="associated_item")] #[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,associated_item")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
fn method_privacy() { } fn method_privacy() { }
} }

View File

@ -277,22 +277,22 @@ trait TraitChangeMethodParametersOrder {
// Add default implementation to method // Add default implementation to method
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
trait TraitAddMethodAutoImplementation { trait TraitAddMethodAutoImplementation {
// ----------------------------------------------------------------------------- // -------------------------------------------------------------
// ------------------------- // -------------------------
// ----------------------------------------------------------------------------- // -------------------------------------------------------------
// ------------------------- // -------------------------
fn method() ; fn method() ;
} }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
trait TraitAddMethodAutoImplementation { trait TraitAddMethodAutoImplementation {
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail2")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail5")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
fn method() {} fn method() {}
} }
@ -795,20 +795,24 @@ trait TraitAddLifetimeBoundToAssociatedType<'a> {
// Add default to associated type // Add default to associated type
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
trait TraitAddDefaultToAssociatedType { trait TraitAddDefaultToAssociatedType {
type Associated; //--------------------------------------------------------------
//--------------------------
//--------------------------------------------------------------
//--------------------------
type Associated ;
fn method(); fn method();
} }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
trait TraitAddDefaultToAssociatedType { trait TraitAddDefaultToAssociatedType {
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail2")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail5")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
type Associated = ReferenceType0; type Associated = ReferenceType0;
@ -839,20 +843,28 @@ trait TraitAddAssociatedConstant {
// Add initializer to associated constant // Add initializer to associated constant
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
trait TraitAddInitializerToAssociatedConstant { trait TraitAddInitializerToAssociatedConstant {
const Value: u32; //--------------------------------------------------------------
//--------------------------
//--------------------------------------------------------------
//--------------------------
const Value: u32 ;
//--------------------------
//--------------------------
//--------------------------
//--------------------------
fn method(); fn method();
} }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
trait TraitAddInitializerToAssociatedConstant { trait TraitAddInitializerToAssociatedConstant {
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail2")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail5")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
const Value: u32 = 1; const Value: u32 = 1;

View File

@ -320,7 +320,11 @@ impl AddItemTrait for Foo {
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
pub trait ChangeHasValueTrait { pub trait ChangeHasValueTrait {
fn method_name(); //--------------------------------------------------------------
//--------------------------
//--------------------------------------------------------------
//--------------------------
fn method_name() ;
} }
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
@ -329,14 +333,14 @@ impl ChangeHasValueTrait for Foo {
} }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(except="hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
pub trait ChangeHasValueTrait { pub trait ChangeHasValueTrait {
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail2")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes,associated_item", cfg="cfail5")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
fn method_name() { } fn method_name() { }
} }
@ -358,22 +362,22 @@ pub trait AddDefaultTrait {
#[cfg(any(cfail1,cfail4))] #[cfg(any(cfail1,cfail4))]
impl AddDefaultTrait for Foo { impl AddDefaultTrait for Foo {
// ---------------------------------------------------- // -------------------------------------------------------------
// ------------------------- // -------------------------
// ---------------------------------------------------- // -------------------------------------------------------------
// ------------------------- // -------------------------
fn method_name() { } fn method_name() { }
} }
#[cfg(not(any(cfail1,cfail4)))] #[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] #[rustc_clean(cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] #[rustc_clean(cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
impl AddDefaultTrait for Foo { impl AddDefaultTrait for Foo {
#[rustc_clean(except="associated_item", cfg="cfail2")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")]
#[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail3")]
#[rustc_clean(except="associated_item", cfg="cfail5")] #[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")]
#[rustc_clean(cfg="cfail6")] #[rustc_clean(cfg="cfail6")]
default fn method_name() { } default fn method_name() { }
} }

View File

@ -220,9 +220,11 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure_ty: Ty<'tcx>, call_ty: Ty<'tc
} }
fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: DefId) -> String { fn get_ufcs_type_name(cx: &LateContext<'_>, method_def_id: DefId) -> String {
match cx.tcx.associated_item(method_def_id).container { let assoc_item = cx.tcx.associated_item(method_def_id);
ty::TraitContainer(def_id) => cx.tcx.def_path_str(def_id), let def_id = assoc_item.container_id(cx.tcx);
ty::ImplContainer(def_id) => { match assoc_item.container {
ty::TraitContainer => cx.tcx.def_path_str(def_id),
ty::ImplContainer => {
let ty = cx.tcx.type_of(def_id); let ty = cx.tcx.type_of(def_id);
match ty.kind() { match ty.kind() {
ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()), ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()),

View File

@ -10,7 +10,7 @@ use clippy_utils::diagnostics::span_lint;
use rustc_ast::ast; use rustc_ast::ast;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty::{self, DefIdTree}; use rustc_middle::ty::DefIdTree;
use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::def_id::CRATE_DEF_ID;
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
@ -153,13 +153,12 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc {
fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) { fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
// If the method is an impl for a trait, don't doc. // If the method is an impl for a trait, don't doc.
match cx.tcx.associated_item(impl_item.def_id).container { if let Some(cid) = cx.tcx.associated_item(impl_item.def_id).impl_container(cx.tcx) {
ty::TraitContainer(_) => return, if cx.tcx.impl_trait_ref(cid).is_some() {
ty::ImplContainer(cid) => { return;
if cx.tcx.impl_trait_ref(cid).is_some() { }
return; } else {
} return;
},
} }
let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id()); let (article, desc) = cx.tcx.article_and_description(impl_item.def_id.to_def_id());

View File

@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
match tit_.kind { match tit_.kind {
hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {}, hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {},
hir::TraitItemKind::Fn(..) => { hir::TraitItemKind::Fn(..) => {
if tit.defaultness.has_value() { if cx.tcx.impl_defaultness(tit.id.def_id).has_value() {
// trait method with default body needs inline in case // trait method with default body needs inline in case
// an impl is not provided // an impl is not provided
let desc = "a default trait method"; let desc = "a default trait method";
@ -151,9 +151,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) => return, hir::ImplItemKind::Const(..) | hir::ImplItemKind::TyAlias(_) => return,
}; };
let trait_def_id = match cx.tcx.associated_item(impl_item.def_id).container { let assoc_item = cx.tcx.associated_item(impl_item.def_id);
TraitContainer(cid) => Some(cid), let container_id = assoc_item.container_id(cx.tcx);
ImplContainer(cid) => cx.tcx.impl_trait_ref(cid).map(|t| t.def_id), let trait_def_id = match assoc_item.container {
TraitContainer => Some(container_id),
ImplContainer => cx.tcx.impl_trait_ref(container_id).map(|t| t.def_id),
}; };
if let Some(trait_def_id) = trait_def_id { if let Some(trait_def_id) = trait_def_id {