Skip to content

Commit bf266dc

Browse files
committed
Propagate TraitImplHeader to hir
1 parent 5bc23ce commit bf266dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+316
-299
lines changed

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 46 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -360,75 +360,30 @@ impl<'hir> LoweringContext<'_, 'hir> {
360360
// lifetime to be added, but rather a reference to a
361361
// parent lifetime.
362362
let itctx = ImplTraitContext::Universal;
363-
let (generics, (trait_ref, lowered_ty)) =
363+
let (generics, (of_trait, lowered_ty)) =
364364
self.lower_generics(ast_generics, id, itctx, |this| {
365-
let modifiers = TraitBoundModifiers {
366-
constness: BoundConstness::Never,
367-
asyncness: BoundAsyncness::Normal,
368-
// we don't use this in bound lowering
369-
polarity: BoundPolarity::Positive,
370-
};
371-
372-
let trait_ref = of_trait.as_ref().map(|of_trait| {
373-
this.lower_trait_ref(
374-
modifiers,
375-
&of_trait.trait_ref,
376-
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
377-
)
378-
});
365+
let of_trait = of_trait
366+
.as_deref()
367+
.map(|of_trait| this.lower_trait_impl_header(of_trait));
379368

380369
let lowered_ty = this.lower_ty(
381370
ty,
382371
ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
383372
);
384373

385-
(trait_ref, lowered_ty)
374+
(of_trait, lowered_ty)
386375
});
387376

388377
let new_impl_items = self
389378
.arena
390379
.alloc_from_iter(impl_items.iter().map(|item| self.lower_impl_item_ref(item)));
391380

392-
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
393-
// to not cause an assertion failure inside the `lower_defaultness` function.
394-
let has_val = true;
395-
let (constness, safety, polarity, defaultness, defaultness_span) = match *of_trait {
396-
Some(box TraitImplHeader {
397-
constness,
398-
safety,
399-
polarity,
400-
defaultness,
401-
trait_ref: _,
402-
}) => {
403-
let constness = self.lower_constness(constness);
404-
let safety = self.lower_safety(safety, hir::Safety::Safe);
405-
let polarity = match polarity {
406-
ImplPolarity::Positive => ImplPolarity::Positive,
407-
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
408-
};
409-
let (defaultness, defaultness_span) =
410-
self.lower_defaultness(defaultness, has_val);
411-
(constness, safety, polarity, defaultness, defaultness_span)
412-
}
413-
None => (
414-
hir::Constness::NotConst,
415-
hir::Safety::Safe,
416-
ImplPolarity::Positive,
417-
hir::Defaultness::Final,
418-
None,
419-
),
420-
};
421-
hir::ItemKind::Impl(self.arena.alloc(hir::Impl {
422-
constness,
423-
safety,
424-
polarity,
425-
defaultness,
426-
defaultness_span,
381+
hir::ItemKind::Impl(hir::Impl {
427382
generics,
428-
of_trait: trait_ref,
383+
of_trait,
429384
self_ty: lowered_ty,
430385
items: new_impl_items,
431-
}))
386+
})
432387
}
433388
ItemKind::Trait(box Trait {
434389
constness,
@@ -999,6 +954,44 @@ impl<'hir> LoweringContext<'_, 'hir> {
999954
self.expr(span, hir::ExprKind::Err(guar))
1000955
}
1001956

957+
fn lower_trait_impl_header(
958+
&mut self,
959+
trait_impl_header: &TraitImplHeader,
960+
) -> &'hir hir::TraitImplHeader<'hir> {
961+
let TraitImplHeader { constness, safety, polarity, defaultness, ref trait_ref } =
962+
*trait_impl_header;
963+
let constness = self.lower_constness(constness);
964+
let safety = self.lower_safety(safety, hir::Safety::Safe);
965+
let polarity = match polarity {
966+
ImplPolarity::Positive => ImplPolarity::Positive,
967+
ImplPolarity::Negative(s) => ImplPolarity::Negative(self.lower_span(s)),
968+
};
969+
// `defaultness.has_value()` is never called for an `impl`, always `true` in order
970+
// to not cause an assertion failure inside the `lower_defaultness` function.
971+
let has_val = true;
972+
let (defaultness, defaultness_span) = self.lower_defaultness(defaultness, has_val);
973+
let modifiers = TraitBoundModifiers {
974+
constness: BoundConstness::Never,
975+
asyncness: BoundAsyncness::Normal,
976+
// we don't use this in bound lowering
977+
polarity: BoundPolarity::Positive,
978+
};
979+
let trait_ref = self.lower_trait_ref(
980+
modifiers,
981+
trait_ref,
982+
ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
983+
);
984+
985+
self.arena.alloc(hir::TraitImplHeader {
986+
constness,
987+
safety,
988+
polarity,
989+
defaultness,
990+
defaultness_span,
991+
trait_ref,
992+
})
993+
}
994+
1002995
fn lower_impl_item(
1003996
&mut self,
1004997
i: &AssocItem,

compiler/rustc_hir/src/hir.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4194,7 +4194,7 @@ impl<'hir> Item<'hir> {
41944194
expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
41954195
ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
41964196

4197-
expect_impl, &'hir Impl<'hir>, ItemKind::Impl(imp), imp;
4197+
expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
41984198
}
41994199
}
42004200

@@ -4372,7 +4372,7 @@ pub enum ItemKind<'hir> {
43724372
TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
43734373

43744374
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
4375-
Impl(&'hir Impl<'hir>),
4375+
Impl(Impl<'hir>),
43764376
}
43774377

43784378
/// Represents an impl block declaration.
@@ -4381,20 +4381,22 @@ pub enum ItemKind<'hir> {
43814381
/// Refer to [`ImplItem`] for an associated item within an impl block.
43824382
#[derive(Debug, Clone, Copy, HashStable_Generic)]
43834383
pub struct Impl<'hir> {
4384+
pub generics: &'hir Generics<'hir>,
4385+
pub of_trait: Option<&'hir TraitImplHeader<'hir>>,
4386+
pub self_ty: &'hir Ty<'hir>,
4387+
pub items: &'hir [ImplItemId],
4388+
}
4389+
4390+
#[derive(Debug, Clone, Copy, HashStable_Generic)]
4391+
pub struct TraitImplHeader<'hir> {
43844392
pub constness: Constness,
43854393
pub safety: Safety,
43864394
pub polarity: ImplPolarity,
43874395
pub defaultness: Defaultness,
43884396
// We do not put a `Span` in `Defaultness` because it breaks foreign crate metadata
43894397
// decoding as `Span`s cannot be decoded when a `Session` is not available.
43904398
pub defaultness_span: Option<Span>,
4391-
pub generics: &'hir Generics<'hir>,
4392-
4393-
/// The trait being implemented, if any.
4394-
pub of_trait: Option<TraitRef<'hir>>,
4395-
4396-
pub self_ty: &'hir Ty<'hir>,
4397-
pub items: &'hir [ImplItemId],
4399+
pub trait_ref: TraitRef<'hir>,
43984400
}
43994401

44004402
impl ItemKind<'_> {
@@ -4756,8 +4758,8 @@ impl<'hir> Node<'hir> {
47564758
/// Get a `hir::Impl` if the node is an impl block for the given `trait_def_id`.
47574759
pub fn impl_block_of_trait(self, trait_def_id: DefId) -> Option<&'hir Impl<'hir>> {
47584760
if let Node::Item(Item { kind: ItemKind::Impl(impl_block), .. }) = self
4759-
&& let Some(trait_ref) = impl_block.of_trait
4760-
&& let Some(trait_id) = trait_ref.trait_def_id()
4761+
&& let Some(of_trait) = impl_block.of_trait
4762+
&& let Some(trait_id) = of_trait.trait_ref.trait_def_id()
47614763
&& trait_id == trait_def_id
47624764
{
47634765
Some(impl_block)
@@ -4952,7 +4954,7 @@ mod size_asserts {
49524954
static_assert_size!(GenericArg<'_>, 16);
49534955
static_assert_size!(GenericBound<'_>, 64);
49544956
static_assert_size!(Generics<'_>, 56);
4955-
static_assert_size!(Impl<'_>, 80);
4957+
static_assert_size!(Impl<'_>, 40);
49564958
static_assert_size!(ImplItem<'_>, 96);
49574959
static_assert_size!(ImplItemKind<'_>, 40);
49584960
static_assert_size!(Item<'_>, 88);
@@ -4967,6 +4969,7 @@ mod size_asserts {
49674969
static_assert_size!(Res, 12);
49684970
static_assert_size!(Stmt<'_>, 32);
49694971
static_assert_size!(StmtKind<'_>, 16);
4972+
static_assert_size!(TraitImplHeader<'_>, 48);
49704973
static_assert_size!(TraitItem<'_>, 88);
49714974
static_assert_size!(TraitItemKind<'_>, 48);
49724975
static_assert_size!(Ty<'_>, 48);

compiler/rustc_hir/src/intravisit.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -590,21 +590,21 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
590590
try_visit!(visitor.visit_generics(generics));
591591
try_visit!(visitor.visit_enum_def(enum_definition));
592592
}
593-
ItemKind::Impl(Impl {
594-
constness: _,
595-
safety: _,
596-
defaultness: _,
597-
polarity: _,
598-
defaultness_span: _,
599-
generics,
600-
of_trait,
601-
self_ty,
602-
items,
603-
}) => {
593+
ItemKind::Impl(Impl { generics, of_trait, self_ty, items }) => {
604594
try_visit!(visitor.visit_generics(generics));
605-
visit_opt!(visitor, visit_trait_ref, of_trait);
595+
if let Some(TraitImplHeader {
596+
constness: _,
597+
safety: _,
598+
polarity: _,
599+
defaultness: _,
600+
defaultness_span: _,
601+
trait_ref,
602+
}) = of_trait
603+
{
604+
try_visit!(visitor.visit_trait_ref(trait_ref));
605+
}
606606
try_visit!(visitor.visit_ty_unambig(self_ty));
607-
walk_list!(visitor, visit_impl_item_ref, *items);
607+
walk_list!(visitor, visit_impl_item_ref, items);
608608
}
609609
ItemKind::Struct(ident, ref generics, ref struct_definition)
610610
| ItemKind::Union(ident, ref generics, ref struct_definition) => {

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 46 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -244,48 +244,48 @@ pub(super) fn check_item<'tcx>(
244244
//
245245
// won't be allowed unless there's an *explicit* implementation of `Send`
246246
// for `T`
247-
hir::ItemKind::Impl(impl_) => {
248-
let header = tcx.impl_trait_header(def_id);
249-
let is_auto = header
250-
.is_some_and(|header| tcx.trait_is_auto(header.trait_ref.skip_binder().def_id));
251-
247+
hir::ItemKind::Impl(ref impl_) => {
252248
crate::impl_wf_check::check_impl_wf(tcx, def_id)?;
253249
let mut res = Ok(());
254-
if let (hir::Defaultness::Default { .. }, true) = (impl_.defaultness, is_auto) {
255-
let sp = impl_.of_trait.as_ref().map_or(item.span, |t| t.path.span);
256-
res = Err(tcx
257-
.dcx()
258-
.struct_span_err(sp, "impls of auto traits cannot be default")
259-
.with_span_labels(impl_.defaultness_span, "default because of this")
260-
.with_span_label(sp, "auto trait")
261-
.emit());
262-
}
263-
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
264-
match header.map(|h| h.polarity) {
265-
// `None` means this is an inherent impl
266-
Some(ty::ImplPolarity::Positive) | None => {
267-
res = res.and(check_impl(tcx, item, impl_.self_ty, &impl_.of_trait));
268-
}
269-
Some(ty::ImplPolarity::Negative) => {
270-
let ast::ImplPolarity::Negative(span) = impl_.polarity else {
271-
bug!("impl_polarity query disagrees with impl's polarity in HIR");
272-
};
273-
// FIXME(#27579): what amount of WF checking do we need for neg impls?
274-
if let hir::Defaultness::Default { .. } = impl_.defaultness {
275-
let mut spans = vec![span];
276-
spans.extend(impl_.defaultness_span);
277-
res = Err(struct_span_code_err!(
278-
tcx.dcx(),
279-
spans,
280-
E0750,
281-
"negative impls cannot be default impls"
282-
)
250+
if let Some(of_trait) = impl_.of_trait {
251+
let header = tcx.impl_trait_header(def_id).unwrap();
252+
let is_auto = tcx.trait_is_auto(header.trait_ref.skip_binder().def_id);
253+
if let (hir::Defaultness::Default { .. }, true) = (of_trait.defaultness, is_auto) {
254+
let sp = of_trait.trait_ref.path.span;
255+
res = Err(tcx
256+
.dcx()
257+
.struct_span_err(sp, "impls of auto traits cannot be default")
258+
.with_span_labels(of_trait.defaultness_span, "default because of this")
259+
.with_span_label(sp, "auto trait")
283260
.emit());
284-
}
285261
}
286-
Some(ty::ImplPolarity::Reservation) => {
287-
// FIXME: what amount of WF checking do we need for reservation impls?
262+
match header.polarity {
263+
ty::ImplPolarity::Positive => {
264+
res = res.and(check_impl(tcx, item, impl_));
265+
}
266+
ty::ImplPolarity::Negative => {
267+
let ast::ImplPolarity::Negative(span) = of_trait.polarity else {
268+
bug!("impl_polarity query disagrees with impl's polarity in HIR");
269+
};
270+
// FIXME(#27579): what amount of WF checking do we need for neg impls?
271+
if let hir::Defaultness::Default { .. } = of_trait.defaultness {
272+
let mut spans = vec![span];
273+
spans.extend(of_trait.defaultness_span);
274+
res = Err(struct_span_code_err!(
275+
tcx.dcx(),
276+
spans,
277+
E0750,
278+
"negative impls cannot be default impls"
279+
)
280+
.emit());
281+
}
282+
}
283+
ty::ImplPolarity::Reservation => {
284+
// FIXME: what amount of WF checking do we need for reservation impls?
285+
}
288286
}
287+
} else {
288+
res = res.and(check_impl(tcx, item, impl_));
289289
}
290290
res
291291
}
@@ -1258,24 +1258,23 @@ pub(crate) fn check_const_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<()
12581258
})
12591259
}
12601260

1261-
#[instrument(level = "debug", skip(tcx, hir_self_ty, hir_trait_ref))]
1261+
#[instrument(level = "debug", skip(tcx, impl_))]
12621262
fn check_impl<'tcx>(
12631263
tcx: TyCtxt<'tcx>,
12641264
item: &'tcx hir::Item<'tcx>,
1265-
hir_self_ty: &hir::Ty<'_>,
1266-
hir_trait_ref: &Option<hir::TraitRef<'_>>,
1265+
impl_: &hir::Impl<'_>,
12671266
) -> Result<(), ErrorGuaranteed> {
12681267
enter_wf_checking_ctxt(tcx, item.owner_id.def_id, |wfcx| {
1269-
match hir_trait_ref {
1270-
Some(hir_trait_ref) => {
1268+
match impl_.of_trait {
1269+
Some(of_trait) => {
12711270
// `#[rustc_reservation_impl]` impls are not real impls and
12721271
// therefore don't need to be WF (the trait's `Self: Trait` predicate
12731272
// won't hold).
12741273
let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
12751274
// Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
12761275
// other `Foo` impls are incoherent.
12771276
tcx.ensure_ok().coherent_trait(trait_ref.def_id)?;
1278-
let trait_span = hir_trait_ref.path.span;
1277+
let trait_span = of_trait.trait_ref.path.span;
12791278
let trait_ref = wfcx.deeply_normalize(
12801279
trait_span,
12811280
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
@@ -1299,12 +1298,12 @@ fn check_impl<'tcx>(
12991298
if let Some(pred) = obligation.predicate.as_trait_clause()
13001299
&& pred.skip_binder().self_ty() == trait_ref.self_ty()
13011300
{
1302-
obligation.cause.span = hir_self_ty.span;
1301+
obligation.cause.span = impl_.self_ty.span;
13031302
}
13041303
if let Some(pred) = obligation.predicate.as_projection_clause()
13051304
&& pred.skip_binder().self_ty() == trait_ref.self_ty()
13061305
{
1307-
obligation.cause.span = hir_self_ty.span;
1306+
obligation.cause.span = impl_.self_ty.span;
13081307
}
13091308
}
13101309

@@ -1321,7 +1320,7 @@ fn check_impl<'tcx>(
13211320
wfcx.register_obligation(Obligation::new(
13221321
tcx,
13231322
ObligationCause::new(
1324-
hir_self_ty.span,
1323+
impl_.self_ty.span,
13251324
wfcx.body_def_id,
13261325
ObligationCauseCode::WellFormed(None),
13271326
),
@@ -1342,7 +1341,7 @@ fn check_impl<'tcx>(
13421341
self_ty,
13431342
);
13441343
wfcx.register_wf_obligation(
1345-
hir_self_ty.span,
1344+
impl_.self_ty.span,
13461345
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
13471346
self_ty.into(),
13481347
);

0 commit comments

Comments
 (0)