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 when using a const fn with an if statement as an array length #75153

Closed
Soveu opened this issue Aug 4, 2020 · 5 comments
Closed

ICE when using a const fn with an if statement as an array length #75153

Soveu opened this issue Aug 4, 2020 · 5 comments
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-const_generics `#![feature(const_generics)]` fixed-by-const-generics Enabling feature `const_generics` fixes the issue. glacier ICE tracked in rust-lang/glacier. 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

@Soveu
Copy link
Contributor

Soveu commented Aug 4, 2020

Code

pub const fn is_zst<T: ?Sized>() -> usize {
    if std::mem::size_of::<T>() == 0 {
        1
    } else {
        0
    }
}

pub struct AtLeastByte<T: ?Sized> {
    value: T,
    pad: [u8; is_zst::<T>()],
}

Meta

rustc --version --verbose:

rustc 1.47.0-nightly (6c8927b0c 2020-07-26)
binary: rustc
commit-hash: 6c8927b0cf80ceee19386026cf9d7fd4fd9d486f
commit-date: 2020-07-26
host: x86_64-unknown-linux-gnu
release: 1.47.0-nightly
LLVM version: 10.0

The bug also does occur in beta version.
Stable versions do not support if statements inside const fn

Error output

error: internal compiler error: src/librustc_middle/ty/subst.rs:554:17: type parameter `T/#0` (T/0) out of range when substituting (root type=Some(fn() -> usize {is_zst::<T>})) substs=[]

thread 'rustc' panicked at 'Box<Any>', /rustc/6c8927b0cf80ceee19386026cf9d7fd4fd9d486f/src/libstd/macros.rs:13:23
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

note: the compiler unexpectedly panicked. this is a bug.

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: rustc 1.47.0-nightly (6c8927b0c 2020-07-26) running on x86_64-unknown-linux-gnu

error: aborting due to previous error
Backtrace

error: internal compiler error: src/librustc_middle/ty/subst.rs:554:17: type parameter `T/#0` (T/0) out of range when substituting (root type=Some(fn() -> usize {is_zst::<T>})) substs=[]

thread 'rustc' panicked at 'Box<Any>', /rustc/6c8927b0cf80ceee19386026cf9d7fd4fd9d486f/src/libstd/macros.rs:13:23
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:78
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:59
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1117
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1508
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:62
   7: std::sys_common::backtrace::print
             at src/libstd/sys_common/backtrace.rs:49
   8: std::panicking::default_hook::{{closure}}
             at src/libstd/panicking.rs:198
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:217
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:530
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::span_bug
  14: rustc_errors::Handler::span_bug
  15: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc_middle::ty::context::tls::with_opt::{{closure}}
  17: rustc_middle::ty::context::tls::with_opt
  18: rustc_middle::util::bug::opt_span_bug_fmt
  19: rustc_middle::util::bug::span_bug_fmt
  20: <rustc_middle::ty::subst::SubstFolder as rustc_middle::ty::fold::TypeFolder>::fold_ty
  21: rustc_middle::ty::fold::TypeFoldable::fold_with
  22: rustc_middle::ty::structural_impls::<impl rustc_middle::ty::fold::TypeFoldable for &rustc_middle::ty::TyS>::super_fold_with
  23: <rustc_middle::ty::subst::SubstFolder as rustc_middle::ty::fold::TypeFolder>::fold_ty
  24: <rustc_middle::ty::subst::SubstFolder as rustc_middle::ty::fold::TypeFolder>::fold_const
  25: rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions
  26: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_operand
  27: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::run
  28: rustc_mir::const_eval::eval_queries::const_eval_raw_provider
  29: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::const_eval_raw>::compute
  30: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  31: rustc_data_structures::stack::ensure_sufficient_stack
  32: rustc_query_system::query::plumbing::get_query_impl
  33: rustc_mir::const_eval::eval_queries::const_eval_validated_provider
  34: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::const_eval_validated>::compute
  35: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  36: rustc_data_structures::stack::ensure_sufficient_stack
  37: rustc_query_system::query::plumbing::get_query_impl
  38: rustc_mir::const_eval::eval_queries::const_eval_validated_provider
  39: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::const_eval_validated>::compute
  40: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  41: rustc_data_structures::stack::ensure_sufficient_stack
  42: rustc_query_system::query::plumbing::get_query_impl
  43: rustc_middle::mir::interpret::queries::<impl rustc_middle::ty::context::TyCtxt>::const_eval_global_id
  44: rustc_middle::mir::interpret::queries::<impl rustc_middle::ty::context::TyCtxt>::const_eval_resolve
  45: <rustc_trait_selection::traits::project::AssocTypeNormalizer as rustc_middle::ty::fold::TypeFolder>::fold_const
  46: rustc_middle::ty::structural_impls::<impl rustc_middle::ty::fold::TypeFoldable for &rustc_middle::ty::TyS>::super_fold_with
  47: <rustc_trait_selection::traits::project::AssocTypeNormalizer as rustc_middle::ty::fold::TypeFolder>::fold_ty
  48: rustc_data_structures::stack::ensure_sufficient_stack
  49: rustc_trait_selection::traits::project::normalize
  50: <rustc_infer::infer::InferCtxt as rustc_trait_selection::infer::InferCtxtExt>::partially_normalize_associated_types_in
  51: rustc_typeck::check::FnCtxt::normalize_associated_types_in
  52: rustc_typeck::check::wfcheck::<impl rustc_typeck::check::FnCtxt>::non_enum_variant::{{closure}}
  53: <core::iter::adapters::Map<I,F> as core::iter::traits::iterator::Iterator>::fold
  54: rustc_infer::infer::InferCtxtBuilder::enter
  55: rustc_typeck::check::wfcheck::check_item_well_formed
  56: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::check_item_well_formed>::compute
  57: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  58: rustc_data_structures::stack::ensure_sufficient_stack
  59: rustc_query_system::query::plumbing::get_query_impl
  60: rustc_query_system::query::plumbing::ensure_query_impl
  61: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  62: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  63: rustc_hir::hir::Crate::par_visit_all_item_likes
  64: rustc_session::session::Session::track_errors
  65: rustc_typeck::check_crate
  66: rustc_interface::passes::analysis
  67: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::analysis>::compute
  68: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  69: rustc_data_structures::stack::ensure_sufficient_stack
  70: rustc_query_system::query::plumbing::get_query_impl
  71: rustc_middle::ty::context::tls::enter_global
  72: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
  73: rustc_span::with_source_map
  74: rustc_interface::interface::create_compiler_and_run
  75: scoped_tls::ScopedKey<T>::set
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: the compiler unexpectedly panicked. this is a bug.

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: rustc 1.47.0-nightly (6c8927b0c 2020-07-26) running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [const_eval_raw] const-evaluating `AtLeastByte::pad::{{constant}}#0`
#1 [const_eval_validated] const-evaluating + checking `AtLeastByte::pad::{{constant}}#0`
#2 [const_eval_validated] const-evaluating + checking `AtLeastByte::pad::{{constant}}#0`
#3 [check_item_well_formed] checking that `AtLeastByte` is well-formed
#4 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

@Soveu Soveu 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 Aug 4, 2020
@lcnr lcnr added A-const-generics Area: const generics (parameters and arguments) F-const_generics `#![feature(const_generics)]` labels Aug 5, 2020
@lcnr
Copy link
Contributor

lcnr commented Aug 5, 2020

This is a lot more related to const generics, see #71922, #67945 and #56445

@lcnr lcnr changed the title ICE inside const fn caused by if statement ICE when using const fn with an if statement as an array length Aug 5, 2020
@lcnr lcnr changed the title ICE when using const fn with an if statement as an array length ICE when using a const fn with an if statement as an array length Aug 5, 2020
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Aug 14, 2020
@varkor
Copy link
Member

varkor commented Sep 13, 2020

This errors correctly with min_const_generics, so hopefully this will be addressed by stabilisation.

@varkor varkor added the fixed-by-const-generics Enabling feature `const_generics` fixes the issue. label Sep 13, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Oct 5, 2020
…lcnr,estebank

Fix missing diagnostic span for `impl Trait` with const generics, and add various tests for `min_const_generics` and `const_generics`

Closes rust-lang#61410.

Adds `min_const_generics` tests for:
- rust-lang#73727
- rust-lang#72293
- rust-lang#67375
- rust-lang#75153
- rust-lang#71922
- rust-lang#69913
- rust-lang#67945
- rust-lang#69239

Adds `const_generics` tests for:
- rust-lang#67375
- rust-lang#75153
- rust-lang#71922
- rust-lang#69913
- rust-lang#67945
- rust-lang#69239

(I only added separate `min_const_generics` and `const_generics` tests if they were handled differently by the two features.)

We need to figure out how to deduplicate when `const_generics` is stabilised, but we can discuss that later. For now, we should be checking neither feature breaks, so require regression tests for both. I've given them identical names when I've added both, which should make it easier to spot them later.

r? @lcnr
@JohnTitor
Copy link
Member

Triage:

The current output with the latest nightly
error: generic parameters may not be used in const operations
  --> /home/runner/work/glacier/glacier/ices/75153.rs:11:24
   |
11 |     pad: [u8; is_zst::<T>()],
   |                        ^ cannot perform const operation using `T`
   |
   = note: type parameters may not be used in const expressions
   = help: use `#![feature(const_generics)]` and `#![feature(const_evaluatable_checked)]` to allow generic const expressions

error[E0277]: the size for values of type `T` cannot be known at compilation time
  --> /home/runner/work/glacier/glacier/ices/75153.rs:10:12
   |
9  | pub struct AtLeastByte<T: ?Sized> {
   |                        - this type parameter needs to be `Sized`
10 |     value: T,
   |            ^ doesn't have a size known at compile-time
   |
   = note: only the last field of a struct may have a dynamically sized type
   = help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
   |
10 |     value: &T,
   |            ^
help: the `Box` type always has a statically known size and allocates its contents in the heap
   |
10 |     value: Box<T>,
   |            ^^^^ ^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0277`.
with #![feature(const_generics)]
error[E0277]: the size for values of type `T` cannot be known at compilation time
   --> src/main.rs:4:28
    |
3   | pub const fn is_zst<T: ?Sized>() -> usize {
    |                     - this type parameter needs to be `Sized`
4   |     if std::mem::size_of::<T>() == 0 {
    |                            ^ doesn't have a size known at compile-time

error[E0277]: the size for values of type `T` cannot be known at compilation time
  --> src/main.rs:12:12
   |
11 | pub struct AtLeastByte<T: ?Sized> {
   |                        - this type parameter needs to be `Sized`
12 |     value: T,
   |            ^ doesn't have a size known at compile-time
   |
   = note: only the last field of a struct may have a dynamically sized type
   = help: change the field's type to have a statically known size
help: borrowed types always have a statically known size
   |
12 |     value: &T,
   |            ^
help: the `Box` type always has a statically known size and allocates its contents in the heap
   |
12 |     value: Box<T>,
   |            ^^^^ ^

error: aborting due to 2 previous errors; 1 warning emitted

Neither is ICE.

@JohnTitor JohnTitor added the E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. label Dec 30, 2020
@lcnr
Copy link
Contributor

lcnr commented Dec 30, 2020

will require feature(const_evaluatable_checked) to work, closing without adding a test as we already have some similar ones

@lcnr lcnr closed this as completed Dec 30, 2020
@estebank
Copy link
Contributor

For future reference, you don't need/want T: ?Sized.

@RalfJung RalfJung added the A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) label Dec 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-eval Area: Constant evaluation, covers all const contexts (static, const fn, ...) A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. E-needs-test Call for participation: An issue has been fixed and does not reproduce, but no test has been added. F-const_generics `#![feature(const_generics)]` fixed-by-const-generics Enabling feature `const_generics` fixes the issue. glacier ICE tracked in rust-lang/glacier. 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

No branches or pull requests

8 participants