diff options
Diffstat (limited to 'compiler')
28 files changed, 245 insertions, 235 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 231752700ba..235573c96e4 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -360,75 +360,30 @@ impl<'hir> LoweringContext<'_, 'hir> { // lifetime to be added, but rather a reference to a // parent lifetime. let itctx = ImplTraitContext::Universal; - let (generics, (trait_ref, lowered_ty)) = + let (generics, (of_trait, lowered_ty)) = self.lower_generics(ast_generics, id, itctx, |this| { - let modifiers = TraitBoundModifiers { - constness: BoundConstness::Never, - asyncness: BoundAsyncness::Normal, - // we don't use this in bound lowering - polarity: BoundPolarity::Positive, - }; - - let trait_ref = of_trait.as_ref().map(|of_trait| { - this.lower_trait_ref( - modifiers, - &of_trait.trait_ref, - ImplTraitContext::Disallowed(ImplTraitPosition::Trait), - ) - }); + let of_trait = of_trait + .as_deref() + .map(|of_trait| this.lower_trait_impl_header(of_trait)); let lowered_ty = this.lower_ty( ty, ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf), ); - (trait_ref, lowered_ty) + (of_trait, lowered_ty) }); let new_impl_items = self .arena .alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item))); - // `defaultness.has_value()` is never called for an `impl`, always `true` in order - // to not cause an assertion failure inside the `lower_defaultness` function. - let has_val = true; - let (constness, safety, polarity, defaultness, defaultness_span) = match *of_trait { - Some(box TraitImplHeader { - constness, - safety, - polarity, - defaultness, - trait_ref: _, - }) => { - let constness = self.lower_constness(constness); - let safety = self.lower_safety(safety, hir::Safety::Safe); - let polarity = match polarity { - ImplPolarity::Positive => ImplPolarity::Positive, - ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)), - }; - let (defaultness, defaultness_span) = - self.lower_defaultness(defaultness, has_val); - (constness, safety, polarity, defaultness, defaultness_span) - } - None => ( - hir::Constness::NotConst, - hir::Safety::Safe, - ImplPolarity::Positive, - hir::Defaultness::Final, - None, - ), - }; - hir::ItemKind::Impl(self.arena.alloc(hir::Impl { - constness, - safety, - polarity, - defaultness, - defaultness_span, + hir::ItemKind::Impl(hir::Impl { generics, - of_trait: trait_ref, + of_trait, self_ty: lowered_ty, items: new_impl_items, - })) + }) } ItemKind::Trait(box Trait { constness, @@ -999,6 +954,44 @@ impl<'hir> LoweringContext<'_, 'hir> { self.expr(span, hir::ExprKind::Err(guar)) } + fn lower_trait_impl_header( + &mut self, + trait_impl_header: &TraitImplHeader, + ) -> &'hir hir::TraitImplHeader<'hir> { + let TraitImplHeader { constness, safety, polarity, defaultness, ref trait_ref } = + *trait_impl_header; + let constness = self.lower_constness(constness); + let safety = self.lower_safety(safety, hir::Safety::Safe); + let polarity = match polarity { + ImplPolarity::Positive => ImplPolarity::Positive, + ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)), + }; + // `defaultness.has_value()` is never called for an `impl`, always `true` in order + // to not cause an assertion failure inside the `lower_defaultness` function. + let has_val = true; + let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val); + let modifiers = TraitBoundModifiers { + constness: BoundConstness::Never, + asyncness: BoundAsyncness::Normal, + // we don't use this in bound lowering + polarity: BoundPolarity::Positive, + }; + let trait_ref = self.lower_trait_ref( + modifiers, + trait_ref, + ImplTraitContext::Disallowed(ImplTraitPosition::Trait), + ); + + self.arena.alloc(hir::TraitImplHeader { + constness, + safety, + polarity, + defaultness, + defaultness_span, + trait_ref, + }) + } + fn lower_impl_item( &mut self, i: &AssocItem, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index 34db6f92d92..d11ffce87cb 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -4194,7 +4194,7 @@ impl<'hir> Item<'hir> { expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>), ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds); - expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp; + expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp; } } @@ -4372,7 +4372,7 @@ pub enum ItemKind<'hir> { TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>), /// An implementation, e.g., `impl<A> Trait for Foo { .. }`. - Impl(&'hir Impl<'hir>), + Impl(Impl<'hir>), } /// Represents an impl block declaration. @@ -4381,6 +4381,14 @@ pub enum ItemKind<'hir> { /// Refer to [`ImplItem`] for an associated item within an impl block. #[derive(Debug, Clone, Copy, HashStable_Generic)] pub struct Impl<'hir> { + pub generics: &'hir Generics<'hir>, + pub of_trait: Option<&'hir TraitImplHeader<'hir>>, + pub self_ty: &'hir Ty<'hir>, + pub items: &'hir [ImplItemId], +} + +#[derive(Debug, Clone, Copy, HashStable_Generic)] +pub struct TraitImplHeader<'hir> { pub constness: Constness, pub safety: Safety, pub polarity: ImplPolarity, @@ -4388,13 +4396,7 @@ pub struct Impl<'hir> { // We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata // decoding as `Span`s cannot be decoded when a `Session` is not available. pub defaultness_span: Option<Span>, - pub generics: &'hir Generics<'hir>, - - /// The trait being implemented, if any. - pub of_trait: Option<TraitRef<'hir>>, - - pub self_ty: &'hir Ty<'hir>, - pub items: &'hir [ImplItemId], + pub trait_ref: TraitRef<'hir>, } impl ItemKind<'_> { @@ -4756,8 +4758,8 @@ impl<'hir> Node<'hir> { /// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`. pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> { if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self - && let Some(trait_ref) = impl_block.of_trait - && let Some(trait_id) = trait_ref.trait_def_id() + && let Some(of_trait) = impl_block.of_trait + && let Some(trait_id) = of_trait.trait_ref.trait_def_id() && trait_id == trait_def_id { Some(impl_block) @@ -4952,7 +4954,7 @@ mod size_asserts { static_assert_size!(GenericArg<'_>, 16); static_assert_size!(GenericBound<'_>, 64); static_assert_size!(Generics<'_>, 56); - static_assert_size!(Impl<'_>, 80); + static_assert_size!(Impl<'_>, 40); static_assert_size!(ImplItem<'_>, 96); static_assert_size!(ImplItemKind<'_>, 40); static_assert_size!(Item<'_>, 88); @@ -4967,6 +4969,7 @@ mod size_asserts { static_assert_size!(Res, 12); static_assert_size!(Stmt<'_>, 32); static_assert_size!(StmtKind<'_>, 16); + static_assert_size!(TraitImplHeader<'_>, 48); static_assert_size!(TraitItem<'_>, 88); static_assert_size!(TraitItemKind<'_>, 48); static_assert_size!(Ty<'_>, 48); diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 23fa466859a..9b2f8ae75fa 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -590,21 +590,21 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V:: try_visit!(visitor.visit_generics(generics)); try_visit!(visitor.visit_enum_def(enum_definition)); } - ItemKind::Impl(Impl { - constness: _, - safety: _, - defaultness: _, - polarity: _, - defaultness_span: _, - generics, - of_trait, - self_ty, - items, - }) => { + ItemKind::Impl(Impl { generics, of_trait, self_ty, items }) => { try_visit!(visitor.visit_generics(generics)); - visit_opt!(visitor, visit_trait_ref, of_trait); + if let Some(TraitImplHeader { + constness: _, + safety: _, + polarity: _, + defaultness: _, + defaultness_span: _, + trait_ref, + }) = of_trait + { + try_visit!(visitor.visit_trait_ref(trait_ref)); + } try_visit!(visitor.visit_ty_unambig(self_ty)); - walk_list!(visitor, visit_impl_item_ref, *items); + walk_list!(visitor, visit_impl_item_ref, items); } ItemKind::Struct(ident, ref generics, ref struct_definition) | ItemKind::Union(ident, ref generics, ref struct_definition) => { diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a62efed13bc..c642435b989 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -244,48 +244,48 @@ pub(super) fn check_item<'tcx>( // // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` - hir::ItemKind::Impl(impl_) => { - let header = tcx.impl_trait_header(def_id); - let is_auto = header - .is_some_and(|header| tcx.trait_is_auto(header.trait_ref.skip_binder().def_id)); - + hir::ItemKind::Impl(ref impl_) => { crate::impl_wf_check::check_impl_wf(tcx, def_id)?; let mut res = Ok(()); - if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) { - let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span); - res = Err(tcx - .dcx() - .struct_span_err(sp, "impls of auto traits cannot be default") - .with_span_labels(impl_.defaultness_span, "default because of this") - .with_span_label(sp, "auto trait") - .emit()); - } - // We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span. - match header.map(|h| h.polarity) { - // `None` means this is an inherent impl - Some(ty::ImplPolarity::Positive) | None => { - res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait)); - } - Some(ty::ImplPolarity::Negative) => { - let ast::ImplPolarity::Negative(span) = impl_.polarity else { - bug!("impl_polarity query disagrees with impl's polarity in HIR"); - }; - // FIXME(#27579): what amount of WF checking do we need for neg impls? - if let hir::Defaultness::Default { .. } = impl_.defaultness { - let mut spans = vec![span]; - spans.extend(impl_.defaultness_span); - res = Err(struct_span_code_err!( - tcx.dcx(), - spans, - E0750, - "negative impls cannot be default impls" - ) + if let Some(of_trait) = impl_.of_trait { + let header = tcx.impl_trait_header(def_id).unwrap(); + let is_auto = tcx.trait_is_auto(header.trait_ref.skip_binder().def_id); + if let (hir::Defaultness::Default { .. }, true) = (of_trait.defaultness, is_auto) { + let sp = of_trait.trait_ref.path.span; + res = Err(tcx + .dcx() + .struct_span_err(sp, "impls of auto traits cannot be default") + .with_span_labels(of_trait.defaultness_span, "default because of this") + .with_span_label(sp, "auto trait") .emit()); - } } - Some(ty::ImplPolarity::Reservation) => { - // FIXME: what amount of WF checking do we need for reservation impls? + match header.polarity { + ty::ImplPolarity::Positive => { + res = res.and(check_impl(tcx, item, impl_)); + } + ty::ImplPolarity::Negative => { + let ast::ImplPolarity::Negative(span) = of_trait.polarity else { + bug!("impl_polarity query disagrees with impl's polarity in HIR"); + }; + // FIXME(#27579): what amount of WF checking do we need for neg impls? + if let hir::Defaultness::Default { .. } = of_trait.defaultness { + let mut spans = vec![span]; + spans.extend(of_trait.defaultness_span); + res = Err(struct_span_code_err!( + tcx.dcx(), + spans, + E0750, + "negative impls cannot be default impls" + ) + .emit()); + } + } + ty::ImplPolarity::Reservation => { + // FIXME: what amount of WF checking do we need for reservation impls? + } } + } else { + res = res.and(check_impl(tcx, item, impl_)); } res } @@ -1258,16 +1258,15 @@ pub(crate) fn check_const_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<() }) } -#[instrument(level = "debug", skip(tcx, hir_self_ty, hir_trait_ref))] +#[instrument(level = "debug", skip(tcx, impl_))] fn check_impl<'tcx>( tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>, - hir_self_ty: &hir::Ty<'_>, - hir_trait_ref: &Option<hir::TraitRef<'_>>, + impl_: &hir::Impl<'_>, ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item.owner_id.def_id, |wfcx| { - match hir_trait_ref { - Some(hir_trait_ref) => { + match impl_.of_trait { + Some(of_trait) => { // `#[rustc_reservation_impl]` impls are not real impls and // therefore don't need to be WF (the trait's `Self: Trait` predicate // won't hold). @@ -1275,7 +1274,7 @@ fn check_impl<'tcx>( // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case // other `Foo` impls are incoherent. tcx.ensure_ok().coherent_trait(trait_ref.def_id)?; - let trait_span = hir_trait_ref.path.span; + let trait_span = of_trait.trait_ref.path.span; let trait_ref = wfcx.deeply_normalize( trait_span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), @@ -1299,12 +1298,12 @@ fn check_impl<'tcx>( if let Some(pred) = obligation.predicate.as_trait_clause() && pred.skip_binder().self_ty() == trait_ref.self_ty() { - obligation.cause.span = hir_self_ty.span; + obligation.cause.span = impl_.self_ty.span; } if let Some(pred) = obligation.predicate.as_projection_clause() && pred.skip_binder().self_ty() == trait_ref.self_ty() { - obligation.cause.span = hir_self_ty.span; + obligation.cause.span = impl_.self_ty.span; } } @@ -1321,7 +1320,7 @@ fn check_impl<'tcx>( wfcx.register_obligation(Obligation::new( tcx, ObligationCause::new( - hir_self_ty.span, + impl_.self_ty.span, wfcx.body_def_id, ObligationCauseCode::WellFormed(None), ), @@ -1342,7 +1341,7 @@ fn check_impl<'tcx>( self_ty, ); wfcx.register_wf_obligation( - hir_self_ty.span, + impl_.self_ty.span, Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)), self_ty.into(), ); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 27948f50a4a..32b175611ce 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -531,8 +531,10 @@ pub(crate) fn coerce_unsized_info<'tcx>( })); } else if diff_fields.len() > 1 { let item = tcx.hir_expect_item(impl_did); - let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(t), .. }) = &item.kind { - t.path.span + let span = if let ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) = + &item.kind + { + of_trait.trait_ref.path.span } else { tcx.def_span(impl_did) }; diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index c75fef9f716..f707196c816 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -384,7 +384,7 @@ fn emit_orphan_check_error<'tcx>( traits::OrphanCheckErr::NonLocalInputType(tys) => { let item = tcx.hir_expect_item(impl_def_id); let impl_ = item.expect_impl(); - let hir_trait_ref = impl_.of_trait.as_ref().unwrap(); + let of_trait = impl_.of_trait.unwrap(); let span = tcx.def_span(impl_def_id); let mut diag = tcx.dcx().create_err(match trait_ref.self_ty().kind() { @@ -401,7 +401,7 @@ fn emit_orphan_check_error<'tcx>( impl_.self_ty.span } else { // Point at `C<B>` in `impl<A, B> for C<B> in D<A>` - hir_trait_ref.path.span + of_trait.trait_ref.path.span }; ty = tcx.erase_regions(ty); diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 8ccbfbbb3b4..b72e743f95b 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -1295,18 +1295,22 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::ImplTrai let icx = ItemCtxt::new(tcx, def_id); let item = tcx.hir_expect_item(def_id); let impl_ = item.expect_impl(); - impl_.of_trait.as_ref().map(|ast_trait_ref| { + let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); + if is_rustc_reservation && impl_.of_trait.is_none() { + tcx.dcx().span_err(item.span, "reservation impls can't be inherent"); + } + impl_.of_trait.map(|of_trait| { let selfty = tcx.type_of(def_id).instantiate_identity(); - check_impl_constness(tcx, impl_.constness, ast_trait_ref); + check_impl_constness(tcx, of_trait.constness, &of_trait.trait_ref); - let trait_ref = icx.lowerer().lower_impl_trait_ref(ast_trait_ref, selfty); + let trait_ref = icx.lowerer().lower_impl_trait_ref(&of_trait.trait_ref, selfty); ty::ImplTraitHeader { trait_ref: ty::EarlyBinder::bind(trait_ref), - safety: impl_.safety, - polarity: polarity_of_impl(tcx, def_id, impl_, item.span), - constness: impl_.constness, + safety: of_trait.safety, + polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation), + constness: of_trait.constness, } }) } @@ -1350,26 +1354,18 @@ fn check_impl_constness( fn polarity_of_impl( tcx: TyCtxt<'_>, - def_id: LocalDefId, - impl_: &hir::Impl<'_>, - span: Span, + of_trait: &hir::TraitImplHeader<'_>, + is_rustc_reservation: bool, ) -> ty::ImplPolarity { - let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); - match &impl_ { - hir::Impl { polarity: hir::ImplPolarity::Negative(span), of_trait, .. } => { + match of_trait.polarity { + hir::ImplPolarity::Negative(span) => { if is_rustc_reservation { - let span = span.to(of_trait.as_ref().map_or(*span, |t| t.path.span)); + let span = span.to(of_trait.trait_ref.path.span); tcx.dcx().span_err(span, "reservation impls can't be negative"); } ty::ImplPolarity::Negative } - hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => { - if is_rustc_reservation { - tcx.dcx().span_err(span, "reservation impls can't be inherent"); - } - ty::ImplPolarity::Positive - } - hir::Impl { polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. } => { + hir::ImplPolarity::Positive => { if is_rustc_reservation { ty::ImplPolarity::Reservation } else { diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs index 8dd13da4fa7..b59dc4bd132 100644 --- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs @@ -158,7 +158,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen if let Node::Item(item) = node { match item.kind { ItemKind::Impl(impl_) => { - if impl_.defaultness.is_default() { + if let Some(of_trait) = impl_.of_trait + && of_trait.defaultness.is_default() + { is_default_impl_trait = tcx .impl_trait_ref(def_id) .map(|t| ty::Binder::dummy(t.instantiate_identity())); diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index eb3492f5de6..8133f9f6823 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -604,13 +604,10 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - match &item.kind { - hir::ItemKind::Impl(hir::Impl { of_trait, .. }) => { - if let Some(of_trait) = of_trait { - self.record_late_bound_vars(of_trait.hir_ref_id, Vec::default()); - } - } - _ => {} + if let hir::ItemKind::Impl(impl_) = item.kind + && let Some(of_trait) = impl_.of_trait + { + self.record_late_bound_vars(of_trait.trait_ref.hir_ref_id, Vec::default()); } match item.kind { hir::ItemKind::Fn { generics, .. } => { @@ -636,7 +633,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> { | hir::ItemKind::Union(_, generics, _) | hir::ItemKind::Trait(_, _, _, _, generics, ..) | hir::ItemKind::TraitAlias(_, generics, ..) - | hir::ItemKind::Impl(&hir::Impl { generics, .. }) => { + | hir::ItemKind::Impl(hir::Impl { generics, .. }) => { // These kinds of items have only early-bound lifetime parameters. self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item)); } @@ -2106,7 +2103,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { // If we have a self type alias (in an impl), try to resolve an // associated item from one of the supertraits of the impl's trait. Res::SelfTyAlias { alias_to: impl_def_id, is_trait_impl: true, .. } => { - let hir::ItemKind::Impl(hir::Impl { of_trait: Some(trait_ref), .. }) = self + let hir::ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), .. }) = self .tcx .hir_node_by_def_id(impl_def_id.expect_local()) .expect_item() @@ -2114,7 +2111,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> { else { return; }; - let Some(trait_def_id) = trait_ref.trait_def_id() else { + let Some(trait_def_id) = of_trait.trait_ref.trait_def_id() else { return; }; let Some((bound_vars, assoc_item)) = BoundVarContext::supertrait_hrtb_vars( diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index 22fb02714dd..62125c99d80 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -251,7 +251,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ .emit_err(crate::errors::SelfInImplSelf { span: spans.into(), note: () }); Ty::new_error(tcx, guar) } - _ => icx.lower_ty(*self_ty), + _ => icx.lower_ty(self_ty), }, ItemKind::Fn { .. } => { let args = ty::GenericArgs::identity_for_item(tcx, def_id); diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs index 835f8e8cdae..8a9f9130fea 100644 --- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs @@ -147,7 +147,11 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { - of_trait: Some(hir::TraitRef { hir_ref_id: id_in_of_trait, .. }), + of_trait: + Some(hir::TraitImplHeader { + trait_ref: hir::TraitRef { hir_ref_id: id_in_of_trait, .. }, + .. + }), .. }), .. diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs index 646ff3ca08d..56998b5b53c 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/lint.rs @@ -200,7 +200,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }) = tcx.hir_node_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id { - let Some(of_trait_ref) = of_trait else { + let Some(of_trait) = of_trait else { diag.span_suggestion_verbose( impl_self_ty.span.shrink_to_hi(), "you might have intended to implement this trait for a given type", @@ -209,10 +209,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { ); return; }; - if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) { + if !of_trait.trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) { return; } - let of_trait_span = of_trait_ref.path.span; + let of_trait_span = of_trait.trait_ref.path.span; // make sure that we are not calling unwrap to abort during the compilation let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 1675aecd2b8..c7b984d9b25 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -2732,7 +2732,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }; let i = tcx.parent_hir_node(fn_hir_id).expect_item().expect_impl(); - let trait_ref = self.lower_impl_trait_ref(i.of_trait.as_ref()?, self.lower_ty(i.self_ty)); + let trait_ref = self.lower_impl_trait_ref(&i.of_trait?.trait_ref, self.lower_ty(i.self_ty)); let assoc = tcx.associated_items(trait_ref.def_id).find_by_ident_and_kind( tcx, diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs index 3fddaee8cef..d8578970adc 100644 --- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs +++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs @@ -154,8 +154,9 @@ pub(super) fn diagnostic_hir_wf_check<'tcx>( hir::ItemKind::TyAlias(_, _, ty) | hir::ItemKind::Static(_, _, ty, _) | hir::ItemKind::Const(_, _, ty, _) => vec![ty], - hir::ItemKind::Impl(impl_) => match &impl_.of_trait { - Some(t) => t + hir::ItemKind::Impl(impl_) => match impl_.of_trait { + Some(of_trait) => of_trait + .trait_ref .path .segments .last() diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 235eec96d74..be5859b57c5 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -690,39 +690,44 @@ impl<'a> State<'a> { let (cb, ib) = self.head("union"); self.print_struct(ident.name, generics, struct_def, item.span, true, cb, ib); } - hir::ItemKind::Impl(&hir::Impl { - constness, - safety, - polarity, - defaultness, - defaultness_span: _, - generics, - ref of_trait, - self_ty, - items, - }) => { + hir::ItemKind::Impl(hir::Impl { generics, of_trait, self_ty, items }) => { let (cb, ib) = self.head(""); - self.print_defaultness(defaultness); - self.print_safety(safety); - self.word_nbsp("impl"); - if let hir::Constness::Const = constness { - self.word_nbsp("const"); - } + let impl_generics = |this: &mut Self| { + this.word_nbsp("impl"); + if !generics.params.is_empty() { + this.print_generic_params(generics.params); + this.space(); + } + }; - if !generics.params.is_empty() { - self.print_generic_params(generics.params); - self.space(); - } + match of_trait { + None => impl_generics(self), + Some(&hir::TraitImplHeader { + constness, + safety, + polarity, + defaultness, + defaultness_span: _, + ref trait_ref, + }) => { + self.print_defaultness(defaultness); + self.print_safety(safety); + + impl_generics(self); + + if let hir::Constness::Const = constness { + self.word_nbsp("const"); + } - if let hir::ImplPolarity::Negative(_) = polarity { - self.word("!"); - } + if let hir::ImplPolarity::Negative(_) = polarity { + self.word("!"); + } - if let Some(t) = of_trait { - self.print_trait_ref(t); - self.space(); - self.word_space("for"); + self.print_trait_ref(trait_ref); + self.space(); + self.word_space("for"); + } } self.print_type(self_ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 2345cdab208..6013430e1ff 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -936,7 +936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Node::ImplItem(item) => { // If it doesn't impl a trait, we can add a return type let Node::Item(&hir::Item { - kind: hir::ItemKind::Impl(&hir::Impl { of_trait, .. }), + kind: hir::ItemKind::Impl(hir::Impl { of_trait, .. }), .. }) = self.tcx.parent_hir_node(item.hir_id()) else { diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index f7430f7af4e..824d592fa6c 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -1103,7 +1103,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_ty.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _) ) || matches!( - of_trait.as_ref().map(|t| t.path.span.ctxt().outer_expn_data().kind), + of_trait.map(|t| t.trait_ref.path.span.ctxt().outer_expn_data().kind), Some(ExpnKind::Macro(MacroKind::Derive, _)) ) => { @@ -1165,13 +1165,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { entry.0.insert(cause_span); entry.1.insert((cause_span, "unsatisfied trait bound introduced here")); } else { - if let Some(trait_ref) = of_trait { - entry.0.insert(trait_ref.path.span); + if let Some(of_trait) = of_trait { + entry.0.insert(of_trait.trait_ref.path.span); } entry.0.insert(self_ty.span); }; - if let Some(trait_ref) = of_trait { - entry.1.insert((trait_ref.path.span, "")); + if let Some(of_trait) = of_trait { + entry.1.insert((of_trait.trait_ref.path.span, "")); } entry.1.insert((self_ty.span, "")); } diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs index dd16117db1c..943fcc0801b 100644 --- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs +++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs @@ -61,8 +61,8 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait { // `Deref` is being implemented for `t` if let hir::ItemKind::Impl(impl_) = item.kind // the trait is a `Deref` implementation - && let Some(trait_) = &impl_.of_trait - && let Some(did) = trait_.trait_def_id() + && let Some(of_trait) = &impl_.of_trait + && let Some(did) = of_trait.trait_ref.trait_def_id() && tcx.is_lang_item(did, LangItem::Deref) // the self type is `dyn t_principal` && let self_ty = tcx.type_of(item.owner_id).instantiate_identity() diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs index 9f02f1f0df3..016ff17f5d7 100644 --- a/compiler/rustc_lint/src/internal.rs +++ b/compiler/rustc_lint/src/internal.rs @@ -582,8 +582,8 @@ impl Diagnostics { for (_hir_id, parent) in cx.tcx.hir_parent_iter(current_id) { debug!(?parent); if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) = parent - && let hir::Impl { of_trait: Some(of_trait), .. } = impl_ - && let Some(def_id) = of_trait.trait_def_id() + && let Some(of_trait) = impl_.of_trait + && let Some(def_id) = of_trait.trait_ref.trait_def_id() && let Some(name) = cx.tcx.get_diagnostic_name(def_id) && matches!(name, sym::Diagnostic | sym::Subdiagnostic | sym::LintDiagnostic) { diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs index b877f909fc0..2dd3425e66c 100644 --- a/compiler/rustc_lint/src/non_local_def.rs +++ b/compiler/rustc_lint/src/non_local_def.rs @@ -129,8 +129,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions { // of the `impl` definition let mut collector = PathCollector { paths: Vec::new() }; collector.visit_ty_unambig(&impl_.self_ty); - if let Some(of_trait) = &impl_.of_trait { - collector.visit_trait_ref(of_trait); + if let Some(of_trait) = impl_.of_trait { + collector.visit_trait_ref(&of_trait.trait_ref); } // 1.5. Remove any path that doesn't resolve to a `DefId` or if it resolve to a diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 10c532b436a..dbdc8a3dbf5 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1155,8 +1155,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { let is_valid = doc_fake_variadic_is_allowed_self_ty(i.self_ty) || if let Some(&[hir::GenericArg::Type(ty)]) = i .of_trait - .as_ref() - .and_then(|trait_ref| trait_ref.path.segments.last()) + .and_then(|of_trait| of_trait.trait_ref.path.segments.last()) .map(|last_segment| last_segment.args().args) { matches!(&ty.kind, hir::TyKind::Tup([_])) @@ -1646,8 +1645,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { && let parent_hir_id = self.tcx.parent_hir_id(hir_id) && let hir::Node::Item(item) = self.tcx.hir_node(parent_hir_id) && let hir::ItemKind::Impl(impl_) = item.kind - && let Some(trait_) = impl_.of_trait - && let Some(def_id) = trait_.trait_def_id() + && let Some(of_trait) = impl_.of_trait + && let Some(def_id) = of_trait.trait_ref.trait_def_id() && self.tcx.is_lang_item(def_id, hir::LangItem::Drop) { return; diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs index e2f223325df..71650c6b9b9 100644 --- a/compiler/rustc_passes/src/stability.rs +++ b/compiler/rustc_passes/src/stability.rs @@ -590,9 +590,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(hir::Impl { - of_trait: Some(t), self_ty, items, constness, .. - }) => { + hir::ItemKind::Impl(hir::Impl { of_trait: Some(of_trait), self_ty, items, .. }) => { let features = self.tcx.features(); if features.staged_api() { let attrs = self.tcx.hir_attrs(item.hir_id()); @@ -628,7 +626,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { { let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true }; c.visit_ty_unambig(self_ty); - c.visit_trait_ref(t); + c.visit_trait_ref(&of_trait.trait_ref); // Skip the lint if the impl is marked as unstable using // #[unstable_feature_bound(..)] @@ -641,7 +639,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { // do not lint when the trait isn't resolved, since resolution error should // be fixed first - if t.path.res != Res::Err + if of_trait.trait_ref.path.res != Res::Err && c.fully_stable && !unstable_feature_bound_in_effect { @@ -655,7 +653,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { } if features.const_trait_impl() - && let hir::Constness::Const = constness + && let hir::Constness::Const = of_trait.constness { let stable_or_implied_stable = match const_stab { None => true, @@ -671,7 +669,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { Some(_) => false, }; - if let Some(trait_id) = t.trait_def_id() + if let Some(trait_id) = of_trait.trait_ref.trait_def_id() && let Some(const_stab) = self.tcx.lookup_const_stability(trait_id) { // the const stability of a trait impl must match the const stability on the trait. @@ -699,14 +697,18 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> { } } - if let hir::Constness::Const = constness - && let Some(def_id) = t.trait_def_id() + if let hir::Constness::Const = of_trait.constness + && let Some(def_id) = of_trait.trait_ref.trait_def_id() { // FIXME(const_trait_impl): Improve the span here. - self.tcx.check_const_stability(def_id, t.path.span, t.path.span); + self.tcx.check_const_stability( + def_id, + of_trait.trait_ref.path.span, + of_trait.trait_ref.path.span, + ); } - for impl_item_ref in *items { + for impl_item_ref in items { let impl_item = self.tcx.associated_item(impl_item_ref.owner_id); if let Some(def_id) = impl_item.trait_item_def_id { diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5d02c02b23c..1bddbd03cc3 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1779,7 +1779,8 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) { if let DefKind::Impl { of_trait: true } = tcx.def_kind(def_id) { let trait_ref = tcx.impl_trait_ref(def_id).unwrap(); let trait_ref = trait_ref.instantiate_identity(); - visitor.span = tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().path.span; + visitor.span = + tcx.hir_expect_item(def_id).expect_impl().of_trait.unwrap().trait_ref.path.span; let _ = visitor.visit_def_id(trait_ref.def_id, "trait", &trait_ref.print_only_trait_path()); } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs index ae72178c052..bc8c8a44405 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs @@ -3471,8 +3471,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .. })) => { let mut spans = Vec::with_capacity(2); - if let Some(trait_ref) = of_trait { - spans.push(trait_ref.path.span); + if let Some(of_trait) = of_trait { + spans.push(of_trait.trait_ref.path.span); } spans.push(self_ty.span); let mut spans: MultiSpan = spans.into(); @@ -3480,7 +3480,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { self_ty.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _) ) || matches!( - of_trait.as_ref().map(|t| t.path.span.ctxt().outer_expn_data().kind), + of_trait.map(|t| t.trait_ref.path.span.ctxt().outer_expn_data().kind), Some(ExpnKind::Macro(MacroKind::Derive, _)) ) { spans.push_span_label( @@ -3592,7 +3592,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .. })) => { let mut spans = vec![self_ty.span]; - spans.extend(of_trait.as_ref().map(|t| t.path.span)); + spans.extend(of_trait.map(|t| t.trait_ref.path.span)); let mut spans: MultiSpan = spans.into(); spans.push_span_label(data.span, "unsatisfied trait bound introduced here"); err.span_note(spans, msg); diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index 37cb64511c7..e9629e31482 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -174,10 +174,10 @@ fn associated_types_for_impl_traits_in_trait_or_impl<'tcx>( }) .collect(), ItemKind::Impl(impl_) => { - let Some(trait_ref) = impl_.of_trait else { + let Some(of_trait) = impl_.of_trait else { return Default::default(); }; - let Some(trait_def_id) = trait_ref.trait_def_id() else { + let Some(trait_def_id) = of_trait.trait_ref.trait_def_id() else { return Default::default(); }; let in_trait_def = tcx.associated_types_for_impl_traits_in_trait_or_impl(trait_def_id); diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs index 6fa763f18ef..cdfb93c4e7d 100644 --- a/compiler/rustc_ty_utils/src/implied_bounds.rs +++ b/compiler/rustc_ty_utils/src/implied_bounds.rs @@ -172,10 +172,12 @@ fn impl_spans(tcx: TyCtxt<'_>, def_id: LocalDefId) -> impl Iterator<Item = Span> let trait_args = impl_ .of_trait .into_iter() - .flat_map(|trait_ref| trait_ref.path.segments.last().unwrap().args().args) + .flat_map(|of_trait| of_trait.trait_ref.path.segments.last().unwrap().args().args) .map(|arg| arg.span()); - let dummy_spans_for_default_args = - impl_.of_trait.into_iter().flat_map(|trait_ref| iter::repeat(trait_ref.path.span)); + let dummy_spans_for_default_args = impl_ + .of_trait + .into_iter() + .flat_map(|of_trait| iter::repeat(of_trait.trait_ref.path.span)); iter::once(impl_.self_ty.span).chain(trait_args).chain(dummy_spans_for_default_args) } else { bug!("unexpected item for impl {def_id:?}: {item:?}") diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs index dc6009116ac..d95660810e5 100644 --- a/compiler/rustc_ty_utils/src/sig_types.rs +++ b/compiler/rustc_ty_utils/src/sig_types.rs @@ -87,7 +87,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>( DefKind::InlineConst | DefKind::Closure | DefKind::SyntheticCoroutineBody => {} DefKind::Impl { of_trait } => { if of_trait { - let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().path.span; + let span = tcx.hir_node_by_def_id(item).expect_item().expect_impl().of_trait.unwrap().trait_ref.path.span; let args = &tcx.impl_trait_ref(item).unwrap().instantiate_identity().args[1..]; try_visit!(visitor.visit(span, args)); } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2e0b16d9227..b22c326b9f2 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -81,7 +81,11 @@ fn sizedness_constraint_for_ty<'tcx>( fn defaultness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Defaultness { match tcx.hir_node_by_def_id(def_id) { hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { defaultness, of_trait: Some(_), .. }), + kind: + hir::ItemKind::Impl(hir::Impl { + of_trait: Some(hir::TraitImplHeader { defaultness, .. }), + .. + }), .. }) | hir::Node::ImplItem(hir::ImplItem { defaultness, .. }) |
