diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs index ddd54f7c2089..d5af74d47fd0 100644 --- a/compiler/rustc_ast_lowering/src/index.rs +++ b/compiler/rustc_ast_lowering/src/index.rs @@ -323,7 +323,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_trait_item_ref(&mut self, ii: &'hir TraitItemRef) { // Do not visit the duplicate information in TraitItemRef. We want to // 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); } @@ -331,8 +331,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { fn visit_impl_item_ref(&mut self, ii: &'hir ImplItemRef) { // Do not visit the duplicate information in ImplItemRef. We want to // map the actual nodes, not the duplicate ones in the *Ref. - let ImplItemRef { id, ident: _, kind: _, span: _, defaultness: _, trait_item_def_id: _ } = - *ii; + let ImplItemRef { id, ident: _, kind: _, span: _, trait_item_def_id: _ } = *ii; self.visit_nested_impl_item(id); } diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 7da49143b461..99f81afc1e25 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -755,17 +755,17 @@ impl<'hir> LoweringContext<'_, 'hir> { let hir_id = self.lower_node_id(i.id); 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) => { 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))); - (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, .. }) => { let names = self.lower_fn_params_to_names(&sig.decl); let (generics, sig) = 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), .. }) => { let asyncness = sig.header.asyncness; @@ -778,7 +778,7 @@ impl<'hir> LoweringContext<'_, 'hir> { FnDeclKind::Trait, 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 { ref generics, @@ -789,7 +789,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }) => { let mut generics = generics.clone(); add_ty_alias_where_clause(&mut generics, where_clauses, false); - self.lower_generics( + let (generics, kind) = self.lower_generics( &generics, i.id, ImplTraitContext::Disallowed(ImplTraitPosition::Generic), @@ -805,7 +805,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ty, ) }, - ) + ); + (generics, kind, ty.is_some()) } AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"), }; @@ -817,28 +818,25 @@ impl<'hir> LoweringContext<'_, 'hir> { generics, kind, span: self.lower_span(i.span), + defaultness: hir::Defaultness::Default { has_value: has_default }, }; self.arena.alloc(item) } fn lower_trait_item_ref(&mut self, i: &AssocItem) -> hir::TraitItemRef { - let (kind, has_default) = match &i.kind { - AssocItemKind::Const(_, _, default) => (hir::AssocItemKind::Const, default.is_some()), - AssocItemKind::TyAlias(box TyAlias { ty, .. }) => { - (hir::AssocItemKind::Type, ty.is_some()) - } - AssocItemKind::Fn(box Fn { sig, body, .. }) => { - (hir::AssocItemKind::Fn { has_self: sig.decl.has_self() }, body.is_some()) + let kind = match &i.kind { + AssocItemKind::Const(..) => hir::AssocItemKind::Const, + AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type, + AssocItemKind::Fn(box Fn { sig, .. }) => { + hir::AssocItemKind::Fn { has_self: sig.decl.has_self() } } AssocItemKind::MacCall(..) => unimplemented!(), }; let id = hir::TraitItemId { def_id: self.local_def_id(i.id) }; - let defaultness = hir::Defaultness::Default { has_value: has_default }; hir::TraitItemRef { id, ident: self.lower_ident(i.ident), span: self.lower_span(i.span), - defaultness, kind, } } @@ -849,6 +847,10 @@ impl<'hir> LoweringContext<'_, '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 { AssocItemKind::Const(_, ty, expr) => { let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Type)); @@ -903,19 +905,16 @@ impl<'hir> LoweringContext<'_, 'hir> { kind, vis_span: self.lower_span(i.vis.span), span: self.lower_span(i.span), + defaultness, }; self.arena.alloc(item) } 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 { id: hir::ImplItemId { def_id: self.local_def_id(i.id) }, ident: self.lower_ident(i.ident), span: self.lower_span(i.span), - defaultness, kind: match &i.kind { AssocItemKind::Const(..) => hir::AssocItemKind::Const, AssocItemKind::TyAlias(..) => hir::AssocItemKind::Type, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 7230555e961c..617433a9803d 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -2222,6 +2222,7 @@ pub struct TraitItem<'hir> { pub generics: &'hir Generics<'hir>, pub kind: TraitItemKind<'hir>, pub span: Span, + pub defaultness: Defaultness, } impl TraitItem<'_> { @@ -2281,6 +2282,7 @@ pub struct ImplItem<'hir> { pub def_id: LocalDefId, pub generics: &'hir Generics<'hir>, pub kind: ImplItemKind<'hir>, + pub defaultness: Defaultness, pub span: Span, pub vis_span: Span, } @@ -3083,7 +3085,6 @@ pub struct TraitItemRef { pub ident: Ident, pub kind: AssocItemKind, pub span: Span, - pub defaultness: Defaultness, } /// A reference from an impl to one of its associated items. This @@ -3098,7 +3099,6 @@ pub struct ImplItemRef { pub ident: Ident, pub kind: AssocItemKind, pub span: Span, - pub defaultness: Defaultness, /// When we are in a trait impl, link to the trait-item's id. pub trait_item_def_id: Option, } @@ -3496,11 +3496,11 @@ mod size_asserts { rustc_data_structures::static_assert_size!(ForeignItem<'static>, 72); rustc_data_structures::static_assert_size!(GenericBound<'_>, 48); 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!(Item<'static>, 80); rustc_data_structures::static_assert_size!(Pat<'static>, 88); 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); } diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 640974115b92..5bb04a9d620e 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -948,6 +948,7 @@ 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>) { visitor.visit_ident(trait_item.ident); visitor.visit_generics(&trait_item.generics); + visitor.visit_defaultness(&trait_item.defaultness); match trait_item.kind { TraitItemKind::Const(ref ty, default) => { visitor.visit_id(trait_item.hir_id()); @@ -980,19 +981,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) { // 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_ident(ident); 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>) { // 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_generics(generics); + visitor.visit_defaultness(defaultness); match *kind { ImplItemKind::Const(ref ty, body) => { visitor.visit_id(impl_item.hir_id()); @@ -1027,12 +1036,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) { // 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: _ } = - *impl_item_ref; + let ImplItemRef { id, ident, ref kind, span: _, trait_item_def_id: _ } = *impl_item_ref; visitor.visit_nested_impl_item(id); visitor.visit_ident(ident); visitor.visit_associated_item_kind(kind); - visitor.visit_defaultness(defaultness); } pub fn walk_struct_def<'v, V: Visitor<'v>>( diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 6b0b5ac7da9a..ef97b95d4006 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1152,7 +1152,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { name, kind, vis: self.get_visibility(id), - defaultness: container.defaultness(), def_id: self.local_def_id(id), trait_item_def_id: self.get_trait_item_def_id(id), container: container.with_def_id(parent), diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index f0886036899a..1fbd6f3795f6 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1212,14 +1212,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; 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 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 { ty::AssocKind::Const => { let rendered = rustc_hir_pretty::to_string( @@ -1227,7 +1222,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { |s| s.print_trait_item(ast_item), ); - record!(self.tables.kind[def_id] <- EntryKind::AssocConst(container)); + record!(self.tables.kind[def_id] <- EntryKind::AssocConst(AssocContainer::Trait)); record!(self.tables.mir_const_qualif[def_id] <- mir::ConstQualifs::default()); record!(self.tables.rendered_const[def_id] <- rendered); } @@ -1244,13 +1239,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tables.asyncness.set(def_id.index, m_sig.header.asyncness); self.tables.constness.set(def_id.index, hir::Constness::NotConst); record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { - container, + container:AssocContainer::Trait, has_self: trait_item.fn_has_self_parameter, }))); } ty::AssocKind::Type => { self.encode_explicit_item_bounds(def_id); - record!(self.tables.kind[def_id] <- EntryKind::AssocType(container)); + record!(self.tables.kind[def_id] <- EntryKind::AssocType(AssocContainer::Trait)); } } match trait_item.kind { @@ -1258,7 +1253,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_item_type(def_id); } ty::AssocKind::Type => { - if trait_item.defaultness.has_value() { + if ast_item.defaultness.has_value() { self.encode_item_type(def_id); } } @@ -1273,23 +1268,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let tcx = self.tcx; 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 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 { ty::AssocKind::Const => { if let hir::ImplItemKind::Const(_, body_id) = ast_item.kind { let qualifs = self.tcx.at(ast_item.span).mir_const_qualif(def_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(AssocContainer::Impl)); record!(self.tables.mir_const_qualif[def_id] <- qualifs); record!(self.tables.rendered_const[def_id] <- const_data); } else { @@ -1308,12 +1296,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; self.tables.constness.set(def_id.index, constness); record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { - container, + container:AssocContainer::Impl, has_self: impl_item.fn_has_self_parameter, }))); } ty::AssocKind::Type => { - record!(self.tables.kind[def_id] <- EntryKind::AssocType(container)); + record!(self.tables.kind[def_id] <- EntryKind::AssocType(AssocContainer::Impl)); } } self.encode_item_type(def_id); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 23198a853693..d93d6323475c 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -439,32 +439,15 @@ struct VariantData { /// a default, or an in impl, whether it's marked "default". #[derive(Copy, Clone, TyEncodable, TyDecodable)] enum AssocContainer { - TraitRequired, - TraitWithDefault, - ImplDefault, - ImplFinal, + Trait, + Impl, } 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, + AssocContainer::Trait => ty::TraitContainer(def_id), + AssocContainer::Impl => ty::ImplContainer(def_id), } } } diff --git a/compiler/rustc_middle/src/traits/specialization_graph.rs b/compiler/rustc_middle/src/traits/specialization_graph.rs index 3c1d0061ae12..2465f8e2533e 100644 --- a/compiler/rustc_middle/src/traits/specialization_graph.rs +++ b/compiler/rustc_middle/src/traits/specialization_graph.rs @@ -217,7 +217,7 @@ impl<'tcx> Ancestors<'tcx> { self.find_map(|node| { if let Some(item) = node.item(tcx, trait_item_def_id) { 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(); if !is_specializable { diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs index eb732148e3eb..af2d26b0579b 100644 --- a/compiler/rustc_middle/src/ty/assoc.rs +++ b/compiler/rustc_middle/src/ty/assoc.rs @@ -47,7 +47,6 @@ pub struct AssocItem { pub name: Symbol, pub kind: AssocKind, pub vis: Visibility, - pub defaultness: hir::Defaultness, pub container: AssocItemContainer, /// If this is an item in an impl of a trait then this is the `DefId` of @@ -64,6 +63,10 @@ impl AssocItem { 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) + } + pub fn signature(&self, tcx: TyCtxt<'_>) -> String { match self.kind { ty::AssocKind::Fn => { diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index 91246051316f..6fbe4ee8f7d3 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -844,7 +844,8 @@ fn foo(&self) -> Self::T { String::new() } hir::AssocItemKind::Type => { // FIXME: account for returning some type in a trait fn impl that has // 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 { diag.span_label( diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index da9d51a29b18..96ce1fef77ec 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1945,7 +1945,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn provided_trait_methods(self, id: DefId) -> impl 'tcx + Iterator { self.associated_items(id) .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. diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 43e4d252676f..ee9f10930c42 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -734,11 +734,12 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { self.reach(item.def_id, item_level).generics().predicates(); 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); reach.generics().predicates(); 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. } else { @@ -1839,14 +1840,13 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { &self, def_id: LocalDefId, assoc_item_kind: AssocItemKind, - defaultness: hir::Defaultness, vis: ty::Visibility, ) { let mut check = self.check(def_id, vis); let (check_ty, is_assoc_ty) = match assoc_item_kind { 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.generics().predicates(); @@ -1878,7 +1878,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { self.check_assoc_item( trait_item_ref.id.def_id, trait_item_ref.kind, - trait_item_ref.defaultness, item_visibility, ); @@ -1951,7 +1950,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> { self.check_assoc_item( impl_item_ref.id.def_id, impl_item_ref.kind, - impl_item_ref.defaultness, impl_item_vis, ); } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 0a0c674d179e..a8e392d692ca 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -697,7 +697,7 @@ impl<'tcx> SaveContext<'tcx> { } Res::Def(HirDefKind::AssocFn, decl_id) => { 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) } else { None diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index 9de4d3a646cb..d22465db85b2 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1988,7 +1988,7 @@ fn confirm_impl_candidate<'cx, 'tcx>( 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 // associated type. This error will be reported by the type // checker method `check_impl_items_against_trait`, so here we @@ -2089,7 +2089,11 @@ fn assoc_def( return Ok(specialization_graph::LeafDef { item: *item, 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) + }, }); } diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs index 3170b29ee697..e9bbc25d0261 100644 --- a/compiler/rustc_trait_selection/src/traits/util.rs +++ b/compiler/rustc_trait_selection/src/traits/util.rs @@ -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 { - 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()).is_final() } pub enum TupleArgumentsFlag { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 4142c999ca74..ffdcf1a72149 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -103,7 +103,6 @@ fn associated_item_from_trait_item_ref( name: trait_item_ref.ident.name, kind, vis: tcx.visibility(def_id), - defaultness: trait_item_ref.defaultness, def_id: def_id.to_def_id(), trait_item_def_id: Some(def_id.to_def_id()), container: ty::TraitContainer(parent_def_id.to_def_id()), @@ -127,7 +126,6 @@ fn associated_item_from_impl_item_ref( name: impl_item_ref.ident.name, kind, vis: tcx.visibility(def_id), - defaultness: impl_item_ref.defaultness, def_id: def_id.to_def_id(), trait_item_def_id: impl_item_ref.trait_item_def_id, container: ty::ImplContainer(parent_def_id.to_def_id()), diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 979e997f2449..bd1d568cd9a0 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -281,7 +281,7 @@ fn resolve_associated_item<'tcx>( } // 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); } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index b1af3051719e..7007e76b86e2 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -70,11 +70,13 @@ fn sized_constraint_for_ty<'tcx>( } fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness { - let item = tcx.hir().expect_item(def_id.expect_local()); - if let hir::ItemKind::Impl(impl_) = &item.kind { - impl_.defaultness - } else { - bug!("`impl_defaultness` called on {:?}", item); + match tcx.hir().get_by_def_id(def_id.expect_local()) { + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.defaultness, + hir::Node::ImplItem(hir::ImplItem { defaultness, .. }) + | hir::Node::TraitItem(hir::TraitItem { defaultness, .. }) => *defaultness, + node => { + bug!("`impl_defaultness` called on {:?}", node); + } } } diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 9497d5c4528c..9c1fd9b30b46 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -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) { let is_implemented = ancestors .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() { missing_items.push(tcx.associated_item(trait_item_id)); diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index faab862cc3c3..543e005c634f 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1007,7 +1007,7 @@ fn check_associated_item( if let ty::AssocItemContainer::TraitContainer(_) = item.container { 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 = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); wfcx.register_wf_obligation(span, loc, ty.into()); diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 36111637a561..91c90d1fa529 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1234,7 +1234,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { match item { 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 .struct_span_err( item.span, diff --git a/compiler/rustc_typeck/src/impl_wf_check.rs b/compiler/rustc_typeck/src/impl_wf_check.rs index 8c26c96816d9..9fee1eaaec98 100644 --- a/compiler/rustc_typeck/src/impl_wf_check.rs +++ b/compiler/rustc_typeck/src/impl_wf_check.rs @@ -106,7 +106,7 @@ fn enforce_impl_params_are_constrained(tcx: TyCtxt<'_>, impl_def_id: LocalDefId) let item = tcx.associated_item(def_id); match item.kind { ty::AssocKind::Type => { - if item.defaultness.has_value() { + if item.defaultness(tcx).has_value() { cgp::parameters_for(&tcx.type_of(def_id), true) } else { Vec::new() diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 5071581e5dc4..c9778b3e5a00 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1101,7 +1101,7 @@ impl<'tcx> Clean<'tcx, Item> for hir::ImplItem<'tcx> { } hir::ImplItemKind::Fn(ref sig, 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)) } hir::ImplItemKind::TyAlias(hir_ty) => { @@ -1140,7 +1140,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { let provided = match self.container { ty::ImplContainer(_) => true, - ty::TraitContainer(_) => self.defaultness.has_value(), + ty::TraitContainer(_) => tcx.impl_defaultness(self.def_id).has_value(), }; if provided { AssocConstItem(ty, ConstantKind::Extern { def_id: self.def_id }) @@ -1179,11 +1179,11 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { let provided = match self.container { ty::ImplContainer(_) => true, - ty::TraitContainer(_) => self.defaultness.has_value(), + ty::TraitContainer(_) => self.defaultness(tcx).has_value(), }; if provided { let defaultness = match self.container { - ty::ImplContainer(_) => Some(self.defaultness), + ty::ImplContainer(_) => Some(self.defaultness(tcx)), ty::TraitContainer(_) => None, }; MethodItem(Box::new(Function { generics, decl }), defaultness) @@ -1280,7 +1280,7 @@ impl<'tcx> Clean<'tcx, Item> for ty::AssocItem { None => bounds.push(GenericBound::maybe_sized(cx)), } - if self.defaultness.has_value() { + if tcx.impl_defaultness(self.def_id).has_value() { AssocTypeItem( Box::new(Typedef { type_: clean_middle_ty( diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 1751249fa626..7d7a63c53847 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -234,7 +234,7 @@ impl UrlFragment { &UrlFragment::Item(def_id) => { let kind = match tcx.def_kind(def_id) { DefKind::AssocFn => { - if tcx.associated_item(def_id).defaultness.has_value() { + if tcx.impl_defaultness(def_id).has_value() { "method." } else { "tymethod." diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs index 0d9532991898..9e14ccd34334 100644 --- a/src/tools/clippy/clippy_lints/src/missing_inline.rs +++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs @@ -105,7 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline { match tit_.kind { hir::TraitItemKind::Const(..) | hir::TraitItemKind::Type(..) => {}, 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 // an impl is not provided let desc = "a default trait method";