diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index ccae524352a59..06738d99bf562 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1186,14 +1186,21 @@ pub(crate) fn check_static_item<'tcx>( ) -> Result<(), ErrorGuaranteed> { enter_wf_checking_ctxt(tcx, item_id, |wfcx| { let span = tcx.ty_span(item_id); - let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(item_id)), ty); + let loc = Some(WellFormedLoc::Ty(item_id)); + let item_ty = wfcx.deeply_normalize(span, loc, ty); let is_foreign_item = tcx.is_foreign_item(item_id); + let is_structurally_foreign_item = || { + let tail = tcx.struct_tail_raw( + item_ty, + &ObligationCause::dummy(), + |ty| wfcx.deeply_normalize(span, loc, ty), + || {}, + ); - let forbid_unsized = !is_foreign_item || { - let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env)); - !matches!(tail.kind(), ty::Foreign(_)) + matches!(tail.kind(), ty::Foreign(_)) }; + let forbid_unsized = !(is_foreign_item && is_structurally_foreign_item()); wfcx.register_wf_obligation(span, Some(WellFormedLoc::Ty(item_id)), item_ty.into()); if forbid_unsized { diff --git a/tests/ui/static/extern-static-normalization-failure-issue-148161.rs b/tests/ui/static/extern-static-normalization-failure-issue-148161.rs new file mode 100644 index 0000000000000..2995c3ed2ec72 --- /dev/null +++ b/tests/ui/static/extern-static-normalization-failure-issue-148161.rs @@ -0,0 +1,21 @@ +// Regression test for https://github.com/rust-lang/rust/issues/148161 +trait Trait { + type Assoc; +} + +impl Trait for u8 { + type Assoc = i8; +} + +struct Struct { + member: T::Assoc, +} + +unsafe extern "C" { + // This used to be an ICE due to normalization failure on ` as Trait>::Assoc` + // while wf checking this static item. + static VAR: Struct; + //~^ ERROR: the trait bound `i8: Trait` is not satisfied +} + +fn main() {} diff --git a/tests/ui/static/extern-static-normalization-failure-issue-148161.stderr b/tests/ui/static/extern-static-normalization-failure-issue-148161.stderr new file mode 100644 index 0000000000000..e2c7d30e2e434 --- /dev/null +++ b/tests/ui/static/extern-static-normalization-failure-issue-148161.stderr @@ -0,0 +1,20 @@ +error[E0277]: the trait bound `i8: Trait` is not satisfied + --> $DIR/extern-static-normalization-failure-issue-148161.rs:17:17 + | +LL | static VAR: Struct; + | ^^^^^^^^^^ the trait `Trait` is not implemented for `i8` + | +help: the trait `Trait` is implemented for `u8` + --> $DIR/extern-static-normalization-failure-issue-148161.rs:6:1 + | +LL | impl Trait for u8 { + | ^^^^^^^^^^^^^^^^^ +note: required by a bound in `Struct` + --> $DIR/extern-static-normalization-failure-issue-148161.rs:10:18 + | +LL | struct Struct { + | ^^^^^ required by this bound in `Struct` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`.