Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICE: failed to normalize const, but it is not generic: UnevaluatedConst #137308

Closed
matthiaskrgr opened this issue Feb 20, 2025 · 2 comments · Fixed by #137399
Closed

ICE: failed to normalize const, but it is not generic: UnevaluatedConst #137308

matthiaskrgr opened this issue Feb 20, 2025 · 2 comments · Fixed by #137399
Assignees
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@matthiaskrgr
Copy link
Member

auto-reduced (treereduce-rust):

//@compile-flags: -Zincremental-verify-ich=yes -Cincremental=<dir> -Cdebuginfo=2 -Clink-dead-code=true -Zvalidate-mir --edition=2024
trait Q {
    const ASSOC: usize;
}

impl<'a, W: ?Sized> Q for [u8; N] {}

pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
    todo!()
}

original:

#![crate_type = "lib"]

trait Q {
    const ASSOC: usize;
}

impl<'a, W: ?Sized> Q for [u8; N] {
    //~^ ERROR: the constant `N` is not of type `usize`
    const ASSOC: usize = 1;
}

pub fn test() -> [u8; <[u8; 13] as Q>::ASSOC] {
    //~^ ERROR: the constant `13` is not of type `u64`
    todo!()
}

Version information

rustc 1.87.0-nightly (ed49386d3 2025-02-19)
binary: rustc
commit-hash: ed49386d3aa3a445a9889707fd405df01723eced
commit-date: 2025-02-19
host: x86_64-unknown-linux-gnu
release: 1.87.0-nightly
LLVM version: 20.1.0

Possibly related line of code:

ct: ty::Const<'tcx>,
) -> Result<ty::Value<'tcx>, &'tcx LayoutError<'tcx>> {
match ct.kind() {
ty::ConstKind::Value(cv) => Ok(cv),
ty::ConstKind::Param(_) | ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) => {
if !ct.has_param() {
bug!("failed to normalize const, but it is not generic: {ct:?}");
}
Err(error(cx, LayoutError::TooGeneric(ty)))
}
ty::ConstKind::Infer(_)
| ty::ConstKind::Bound(..)
| ty::ConstKind::Placeholder(_)

Command:
/home/matthias/.rustup/toolchains/master/bin/rustc -Zincremental-verify-ich=yes -Cincremental=<dir> -Cdebuginfo=2 -Clink-dead-code=true -Zvalidate-mir --edition=2024

Program output

error[E0425]: cannot find value `N` in this scope
 --> /tmp/icemaker_global_tempdir.MNIZNQo6CYeL/rustc_testrunner_tmpdir_reporting.Qq5ognT5KM0J/mvce.rs:5:32
  |
5 | impl<'a, W: ?Sized> Q for [u8; N] {}
  |                                ^ not found in this scope

error[E0601]: `main` function not found in crate `mvce`
 --> /tmp/icemaker_global_tempdir.MNIZNQo6CYeL/rustc_testrunner_tmpdir_reporting.Qq5ognT5KM0J/mvce.rs:9:2
  |
9 | }
  |  ^ consider adding a `main` function to `/tmp/icemaker_global_tempdir.MNIZNQo6CYeL/rustc_testrunner_tmpdir_reporting.Qq5ognT5KM0J/mvce.rs`

error[E0207]: the type parameter `W` is not constrained by the impl trait, self type, or predicates
 --> /tmp/icemaker_global_tempdir.MNIZNQo6CYeL/rustc_testrunner_tmpdir_reporting.Qq5ognT5KM0J/mvce.rs:5:10
  |
5 | impl<'a, W: ?Sized> Q for [u8; N] {}
  |          ^ unconstrained type parameter

error: internal compiler error: compiler/rustc_ty_utils/src/layout.rs:152:17: failed to normalize const, but it is not generic: UnevaluatedConst { def: DefId(0:10 ~ mvce[846c]::test::{constant#0}), args: [] }


thread 'rustc' panicked at compiler/rustc_ty_utils/src/layout.rs:152:17:
Box<dyn Any>
stack backtrace:
   0:     0x7d3ff999a8e4 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h8474fc63c522d8ef
   1:     0x7d3ffa21a2ac - core::fmt::write::h807495cdc673c9ad
   2:     0x7d3ffb18d291 - std::io::Write::write_fmt::ha095d9f81ce0ab0f
   3:     0x7d3ff999a742 - std::sys::backtrace::BacktraceLock::print::h6697e7571ddb1a7a
   4:     0x7d3ff999cf4e - std::panicking::default_hook::{{closure}}::h809b6cc791b58376
   5:     0x7d3ff999cb24 - std::panicking::default_hook::h552e31dd2ff71c94
   6:     0x7d3ff8ae8d17 - std[751aac3a1d4a21ec]::panicking::update_hook::<alloc[e70108a9cb6abf43]::boxed::Box<rustc_driver_impl[2db46e11a3788224]::install_ice_hook::{closure#1}>>::{closure#0}
   7:     0x7d3ff999d7c3 - std::panicking::rust_panic_with_hook::h31b9a9fc06967d1a
   8:     0x7d3ff8b24bb1 - std[751aac3a1d4a21ec]::panicking::begin_panic::<rustc_errors[a11b7d5dcf14c424]::ExplicitBug>::{closure#0}
   9:     0x7d3ff8b18fc6 - std[751aac3a1d4a21ec]::sys::backtrace::__rust_end_short_backtrace::<std[751aac3a1d4a21ec]::panicking::begin_panic<rustc_errors[a11b7d5dcf14c424]::ExplicitBug>::{closure#0}, !>
  10:     0x7d3ff8b18da7 - std[751aac3a1d4a21ec]::panicking::begin_panic::<rustc_errors[a11b7d5dcf14c424]::ExplicitBug>
  11:     0x7d3ff8b2e531 - <rustc_errors[a11b7d5dcf14c424]::diagnostic::BugAbort as rustc_errors[a11b7d5dcf14c424]::diagnostic::EmissionGuarantee>::emit_producing_guarantee
  12:     0x7d3ff90feb06 - rustc_middle[cad254c74eefe1b7]::util::bug::opt_span_bug_fmt::<rustc_span[3242d24a3aa68a91]::span_encoding::Span>::{closure#0}
  13:     0x7d3ff90e7d7a - rustc_middle[cad254c74eefe1b7]::ty::context::tls::with_opt::<rustc_middle[cad254c74eefe1b7]::util::bug::opt_span_bug_fmt<rustc_span[3242d24a3aa68a91]::span_encoding::Span>::{closure#0}, !>::{closure#0}
  14:     0x7d3ff90e7c0b - rustc_middle[cad254c74eefe1b7]::ty::context::tls::with_context_opt::<rustc_middle[cad254c74eefe1b7]::ty::context::tls::with_opt<rustc_middle[cad254c74eefe1b7]::util::bug::opt_span_bug_fmt<rustc_span[3242d24a3aa68a91]::span_encoding::Span>::{closure#0}, !>::{closure#0}, !>
  15:     0x7d3ff7784de0 - rustc_middle[cad254c74eefe1b7]::util::bug::bug_fmt
  16:     0x7d3ffa7e6469 - rustc_ty_utils[5f7f94c7724baf90]::layout::layout_of_uncached
  17:     0x7d3ffa7d3d24 - rustc_ty_utils[5f7f94c7724baf90]::layout::layout_of
  18:     0x7d3ffa7d3c88 - rustc_query_impl[db8619f7f72bce84]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[db8619f7f72bce84]::query_impl::layout_of::dynamic_query::{closure#2}::{closure#0}, rustc_middle[cad254c74eefe1b7]::query::erase::Erased<[u8; 16usize]>>
  19:     0x7d3ffa7bf84d - rustc_query_system[61afea02fdc7dc5c]::query::plumbing::try_execute_query::<rustc_query_impl[db8619f7f72bce84]::DynamicConfig<rustc_query_system[61afea02fdc7dc5c]::query::caches::DefaultCache<rustc_middle[cad254c74eefe1b7]::ty::PseudoCanonicalInput<rustc_middle[cad254c74eefe1b7]::ty::Ty>, rustc_middle[cad254c74eefe1b7]::query::erase::Erased<[u8; 16usize]>>, false, true, false>, rustc_query_impl[db8619f7f72bce84]::plumbing::QueryCtxt, true>
  20:     0x7d3ffa7be452 - rustc_query_impl[db8619f7f72bce84]::query_impl::layout_of::get_query_incr::__rust_end_short_backtrace
  21:     0x7d3ffb0c80f0 - <rustc_mir_transform[5f9d0e5befb1dd62]::known_panics_lint::KnownPanicsLint as rustc_mir_transform[5f9d0e5befb1dd62]::pass_manager::MirLint>::run_lint
  22:     0x7d3ffa20979b - rustc_mir_transform[5f9d0e5befb1dd62]::run_analysis_to_runtime_passes
  23:     0x7d3ffa5cf2d9 - rustc_mir_transform[5f9d0e5befb1dd62]::mir_drops_elaborated_and_const_checked
  24:     0x7d3ffa5cef1f - rustc_query_impl[db8619f7f72bce84]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[db8619f7f72bce84]::query_impl::mir_drops_elaborated_and_const_checked::dynamic_query::{closure#2}::{closure#0}, rustc_middle[cad254c74eefe1b7]::query::erase::Erased<[u8; 8usize]>>
  25:     0x7d3ffa5c6d17 - rustc_query_system[61afea02fdc7dc5c]::query::plumbing::try_execute_query::<rustc_query_impl[db8619f7f72bce84]::DynamicConfig<rustc_data_structures[7f723801f239d808]::vec_cache::VecCache<rustc_span[3242d24a3aa68a91]::def_id::LocalDefId, rustc_middle[cad254c74eefe1b7]::query::erase::Erased<[u8; 8usize]>, rustc_query_system[61afea02fdc7dc5c]::dep_graph::graph::DepNodeIndex>, false, false, false>, rustc_query_impl[db8619f7f72bce84]::plumbing::QueryCtxt, true>
  26:     0x7d3ffa6b0e21 - rustc_query_impl[db8619f7f72bce84]::query_impl::mir_drops_elaborated_and_const_checked::get_query_incr::__rust_end_short_backtrace
  27:     0x7d3ffa5cc3e2 - rustc_interface[8d7befe99ce7adde]::passes::run_required_analyses
  28:     0x7d3ffb18923a - rustc_interface[8d7befe99ce7adde]::passes::analysis
  29:     0x7d3ffb189219 - rustc_query_impl[db8619f7f72bce84]::plumbing::__rust_begin_short_backtrace::<rustc_query_impl[db8619f7f72bce84]::query_impl::analysis::dynamic_query::{closure#2}::{closure#0}, rustc_middle[cad254c74eefe1b7]::query::erase::Erased<[u8; 0usize]>>
  30:     0x7d3ffb184b19 - rustc_query_system[61afea02fdc7dc5c]::query::plumbing::try_execute_query::<rustc_query_impl[db8619f7f72bce84]::DynamicConfig<rustc_query_system[61afea02fdc7dc5c]::query::caches::SingleCache<rustc_middle[cad254c74eefe1b7]::query::erase::Erased<[u8; 0usize]>>, false, false, false>, rustc_query_impl[db8619f7f72bce84]::plumbing::QueryCtxt, true>
  31:     0x7d3ffb184522 - rustc_query_impl[db8619f7f72bce84]::query_impl::analysis::get_query_incr::__rust_end_short_backtrace
  32:     0x7d3ffb248f3c - rustc_interface[8d7befe99ce7adde]::passes::create_and_enter_global_ctxt::<core[5038f2ec8886dbab]::option::Option<rustc_interface[8d7befe99ce7adde]::queries::Linker>, rustc_driver_impl[2db46e11a3788224]::run_compiler::{closure#0}::{closure#2}>::{closure#2}::{closure#0}
  33:     0x7d3ffb23c8ab - rustc_interface[8d7befe99ce7adde]::interface::run_compiler::<(), rustc_driver_impl[2db46e11a3788224]::run_compiler::{closure#0}>::{closure#1}
  34:     0x7d3ffb102dc8 - std[751aac3a1d4a21ec]::sys::backtrace::__rust_begin_short_backtrace::<rustc_interface[8d7befe99ce7adde]::util::run_in_thread_with_globals<rustc_interface[8d7befe99ce7adde]::util::run_in_thread_pool_with_globals<rustc_interface[8d7befe99ce7adde]::interface::run_compiler<(), rustc_driver_impl[2db46e11a3788224]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>
  35:     0x7d3ffb1031f4 - <<std[751aac3a1d4a21ec]::thread::Builder>::spawn_unchecked_<rustc_interface[8d7befe99ce7adde]::util::run_in_thread_with_globals<rustc_interface[8d7befe99ce7adde]::util::run_in_thread_pool_with_globals<rustc_interface[8d7befe99ce7adde]::interface::run_compiler<(), rustc_driver_impl[2db46e11a3788224]::run_compiler::{closure#0}>::{closure#1}, ()>::{closure#0}, ()>::{closure#0}::{closure#0}, ()>::{closure#1} as core[5038f2ec8886dbab]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
  36:     0x7d3ffb103baf - std::sys::pal::unix::thread::Thread::new::thread_start::ha52e702df20ec6b5
  37:     0x7d3ff529470a - <unknown>
  38:     0x7d3ff5318aac - <unknown>
  39:                0x0 - <unknown>

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: please make sure that you have updated to the latest nightly

note: rustc 1.87.0-nightly (ed49386d3 2025-02-19) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z incremental-verify-ich=yes -C incremental=[REDACTED] -C debuginfo=2 -C link-dead-code=true -Z validate-mir

query stack during panic:
#0 [layout_of] computing layout of `[u8; <[u8; 13] as Q>::ASSOC]`
#1 [mir_drops_elaborated_and_const_checked] elaborating drops for `test`
#2 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to 4 previous errors

Some errors have detailed explanations: E0207, E0425, E0601.
For more information about an error, try `rustc --explain E0207`.

@matthiaskrgr matthiaskrgr added C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 20, 2025
@rustbot rustbot added the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 20, 2025
@matthiaskrgr
Copy link
Member Author

#![crate_type="lib"]
trait A {
    const B: usize;
}
impl<C: ?Sized> A for [u8; D] {}
fn e() -> [u8; <[u8; 3]>::B] {
    todo!()
}

@lukas-code
Copy link
Member

Caused by 7a667d2, looks like that bug needs to be delayed.

@lukas-code lukas-code self-assigned this Feb 20, 2025
@lukas-code lukas-code removed the needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. label Feb 20, 2025
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 21, 2025
…ler-errors

fix ICE in layout computation with unnormalizable const

The first commit reverts half of 7a667d2, where I removed a case from `layout_of` for handling non-generic unevaluated consts in array length, that I incorrectly assumed to be unreachable. This can actually happen with the combination of `feature(generic_const_exprs)` and `feature(trivial_bounds)`, because GCE makes anon consts inherit their parent's predicates and with an impossible predicate like `u8: A` it's possible to have an array whose length is an associated const like `<u8 as A>::B` that is not generic, but also can't be normalized:

```rust
#![feature(generic_const_exprs)]
#![feature(trivial_bounds)]

trait A {
    const B: usize;
}

// With GCE + trivial bounds this definition is not a compile error.
// Computing the layout of this type shouldn't ICE.
struct S([u8; <u8 as A>::B])
where
    u8: A;
```

---

The first commit also incidentally fixes rust-lang#137308, which also managed to get an unnormalizable assoc const into an array length:

```rust
trait A {
    const B: usize;
}

impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained
    const B: usize = 42;
}

// Computing the layout of this type shouldn't ICE, even with the compile error above.
struct S([u8; <u8 as A>::B]);
```

This happens, because we bail out from `codegen_select_candidate` with an error if the selected impl has unconstrained params to avoid leaking infer vars out of a query. `Instance::try_resolve` will then return `Ok(None)`, which for assoc consts roughly means "this const can't be evaluated in a generic context" and is treated as such: https://github.com/rust-lang/rust/blob/71e06b9c59d6af50fdc55aed75620493d29baf98/compiler/rustc_middle/src/mir/interpret/queries.rs#L84 (and this can ICE if the const isn't generic: rust-lang#135617).

However, here `<u8 as A>::B` is definitely not "too generic" and also not unresolvable due to an unsatisfiable `u8: A` bound, so I've included the second commit to change the result of `Instance::try_resolve` from `Ok(None)` to `Err(ErrorGuaranteed)` when resolving an assoc item to an impl with unconstrained generic params. This has the effect that `<u8 as A>::B` will now be normalized to `ConstKind::Error` in the example above.

This properly fixes rust-lang#137308, by no longer treating `<u8 as A>::B` as unresolvable even though it clearly has a unique impl that it resolves to. It also has the effect of changing the layout error from `Unknown` ("the type may be valid but has no sensible layout") to `ReferencesError` ("a non-layout error is reported elsewhere") which seems more appropriate.

r? `@compiler-errors`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Feb 21, 2025
…ler-errors

fix ICE in layout computation with unnormalizable const

The first commit reverts half of 7a667d2, where I removed a case from `layout_of` for handling non-generic unevaluated consts in array length, that I incorrectly assumed to be unreachable. This can actually happen with the combination of `feature(generic_const_exprs)` and `feature(trivial_bounds)`, because GCE makes anon consts inherit their parent's predicates and with an impossible predicate like `u8: A` it's possible to have an array whose length is an associated const like `<u8 as A>::B` that is not generic, but also can't be normalized:

```rust
#![feature(generic_const_exprs)]
#![feature(trivial_bounds)]

trait A {
    const B: usize;
}

// With GCE + trivial bounds this definition is not a compile error.
// Computing the layout of this type shouldn't ICE.
struct S([u8; <u8 as A>::B])
where
    u8: A;
```

---

The first commit also incidentally fixes rust-lang#137308, which also managed to get an unnormalizable assoc const into an array length:

```rust
trait A {
    const B: usize;
}

impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained
    const B: usize = 42;
}

// Computing the layout of this type shouldn't ICE, even with the compile error above.
struct S([u8; <u8 as A>::B]);
```

This happens, because we bail out from `codegen_select_candidate` with an error if the selected impl has unconstrained params to avoid leaking infer vars out of a query. `Instance::try_resolve` will then return `Ok(None)`, which for assoc consts roughly means "this const can't be evaluated in a generic context" and is treated as such: https://github.com/rust-lang/rust/blob/71e06b9c59d6af50fdc55aed75620493d29baf98/compiler/rustc_middle/src/mir/interpret/queries.rs#L84 (and this can ICE if the const isn't generic: rust-lang#135617).

However, here `<u8 as A>::B` is definitely not "too generic" and also not unresolvable due to an unsatisfiable `u8: A` bound, so I've included the second commit to change the result of `Instance::try_resolve` from `Ok(None)` to `Err(ErrorGuaranteed)` when resolving an assoc item to an impl with unconstrained generic params. This has the effect that `<u8 as A>::B` will now be normalized to `ConstKind::Error` in the example above.

This properly fixes rust-lang#137308, by no longer treating `<u8 as A>::B` as unresolvable even though it clearly has a unique impl that it resolves to. It also has the effect of changing the layout error from `Unknown` ("the type may be valid but has no sensible layout") to `ReferencesError` ("a non-layout error is reported elsewhere") which seems more appropriate.

r? ``@compiler-errors``
@bors bors closed this as completed in 6352044 Feb 22, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Feb 22, 2025
Rollup merge of rust-lang#137399 - lukas-code:oopsie-woopsie, r=compiler-errors

fix ICE in layout computation with unnormalizable const

The first commit reverts half of 7a667d2, where I removed a case from `layout_of` for handling non-generic unevaluated consts in array length, that I incorrectly assumed to be unreachable. This can actually happen with the combination of `feature(generic_const_exprs)` and `feature(trivial_bounds)`, because GCE makes anon consts inherit their parent's predicates and with an impossible predicate like `u8: A` it's possible to have an array whose length is an associated const like `<u8 as A>::B` that is not generic, but also can't be normalized:

```rust
#![feature(generic_const_exprs)]
#![feature(trivial_bounds)]

trait A {
    const B: usize;
}

// With GCE + trivial bounds this definition is not a compile error.
// Computing the layout of this type shouldn't ICE.
struct S([u8; <u8 as A>::B])
where
    u8: A;
```

---

The first commit also incidentally fixes rust-lang#137308, which also managed to get an unnormalizable assoc const into an array length:

```rust
trait A {
    const B: usize;
}

impl<C: ?Sized> A for u8 { //~ ERROR: the type parameter `C` is not constrained
    const B: usize = 42;
}

// Computing the layout of this type shouldn't ICE, even with the compile error above.
struct S([u8; <u8 as A>::B]);
```

This happens, because we bail out from `codegen_select_candidate` with an error if the selected impl has unconstrained params to avoid leaking infer vars out of a query. `Instance::try_resolve` will then return `Ok(None)`, which for assoc consts roughly means "this const can't be evaluated in a generic context" and is treated as such: https://github.com/rust-lang/rust/blob/71e06b9c59d6af50fdc55aed75620493d29baf98/compiler/rustc_middle/src/mir/interpret/queries.rs#L84 (and this can ICE if the const isn't generic: rust-lang#135617).

However, here `<u8 as A>::B` is definitely not "too generic" and also not unresolvable due to an unsatisfiable `u8: A` bound, so I've included the second commit to change the result of `Instance::try_resolve` from `Ok(None)` to `Err(ErrorGuaranteed)` when resolving an assoc item to an impl with unconstrained generic params. This has the effect that `<u8 as A>::B` will now be normalized to `ConstKind::Error` in the example above.

This properly fixes rust-lang#137308, by no longer treating `<u8 as A>::B` as unresolvable even though it clearly has a unique impl that it resolves to. It also has the effect of changing the layout error from `Unknown` ("the type may be valid but has no sensible layout") to `ReferencesError` ("a non-layout error is reported elsewhere") which seems more appropriate.

r? ```@compiler-errors```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants