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 from const item in lifetime-parametric impl #56445

Closed
thejpster opened this issue Dec 2, 2018 · 18 comments · Fixed by #83569
Closed

ICE from const item in lifetime-parametric impl #56445

thejpster opened this issue Dec 2, 2018 · 18 comments · Fixed by #83569
Assignees
Labels
A-const-generics Area: const generics (parameters and arguments) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug. const-generics-fixed-by-const_generics A bug that has been fixed once `const_generics` is enabled. D-confusing Diagnostics: Confusing error or lint that should be reworked. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. 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)]` 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

@thejpster
Copy link
Contributor

thejpster commented Dec 2, 2018

Reduced test case (play) from comment below:

struct OnDiskDirEntry<'a> { _s: &'a usize }

impl<'a> OnDiskDirEntry<'a> {
    const LFN_FRAGMENT_LEN: usize = 2;

    fn lfn_contents(&self) -> [char; Self::LFN_FRAGMENT_LEN] { loop { } }
}

Another repro case: #56445 (comment)

Original bug report follows


If I run cargo test on https://github.com/thejpster/embedded-sdmmc-rs/tree/generates_ice, I get an ICE:

user@host:~/Documents/programming/embedded-sdmmc$ cargo test
   Compiling embedded-sdmmc v0.1.0 (/home/jonathan/Documents/programming/embedded-sdmmc)                                                                                                                    
thread 'main' panicked at 'assertion failed: `(left == right)`                                                                                                                                              
  left: `Some(NodeId(1093))`,                                                                                                                                                                               
 right: `None`: free_scope: DefId(0/0:72 ~ embedded_sdmmc[4f8a]::fat[0]::{{impl}}[4]) not recognized by the region scope tree for None / Some(DefId(0/0:79 ~ embedded_sdmmc[4f8a]::fat[0]::{{impl}}[4]::lfn_contents[0]))', librustc/middle/region.rs:673:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.                                                                                                                                                          
                                                                                                                                                                                                            
error: internal compiler error: unexpected panic                                                                                                                                                            
                                                                                                                                                                                                            
note: the compiler unexpectedly panicked. this is a bug.                                                                                                                                                    
                                                                                                                                                                                                            
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports                                                                                           
                                                                                                                                                                                                            
note: rustc 1.31.0-beta.19 (42053f9f0 2018-11-26) running on x86_64-unknown-linux-gnu                                                                                                                       
                                                                                                                                                                                                            
note: compiler flags: -C debuginfo=2 -C incremental --crate-type lib                                                                                                                                        
                                                                                                                                                                                                            
note: some of the compiler flags provided by cargo are hidden                                                                                                                                               
                                                                                                                                                                                                            
error: Could not compile `embedded-sdmmc`.                                                                                                                                                                  
warning: build failed, waiting for other jobs to finish...
thread 'main' panicked at 'assertion failed: `(left == right)`                                                                                                                                              
  left: `Some(NodeId(1090))`,                                                                                                                                                                               
 right: `None`: free_scope: DefId(0/0:71 ~ embedded_sdmmc[be94]::fat[0]::{{impl}}[4]) not recognized by the region scope tree for None / Some(DefId(0/0:78 ~ embedded_sdmmc[be94]::fat[0]::{{impl}}[4]::lfn_contents[0]))', librustc/middle/region.rs:673:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.                                                                                                                                                          
                                                                                                                                                                                                            
error: internal compiler error: unexpected panic                                                                                                                                                            
                                                                                                                                                                                                            
note: the compiler unexpectedly panicked. this is a bug.                                                                                                                                                    
                                                                                                                                                                                                            
note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports                                                                                           
                                                                                                                                                                                                            
note: rustc 1.31.0-beta.19 (42053f9f0 2018-11-26) running on x86_64-unknown-linux-gnu                                                                                                                       
                                                                                                                                                                                                            
note: compiler flags: -C debuginfo=2 -C incremental                                                                                                                                                         
                                                                                                                                                                                                            
note: some of the compiler flags provided by cargo are hidden                                                                                                                                               
                                                                                                                                                                                                            
error: Could not compile `embedded-sdmmc`.                                                                                                                                                                  

To learn more, run the command again with --verbose.

user@host:~/Documents/programming/embedded-sdmmc$ cargo +nightly test
   Compiling embedded-sdmmc v0.1.0 (/home/jonathan/Documents/programming/embedded-sdmmc)
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Some(NodeId(1093))`,
 right: `None`: free_scope: DefId(0/0:72 ~ embedded_sdmmc[46a7]::fat[0]::{{impl}}[4]) not recognized by the region scope tree for None / Some(DefId(0/0:79 ~ embedded_sdmmc[46a7]::fat[0]::{{impl}}[4]::lfn_contents[0]))', src/librustc/middle/region.rs:673:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.

error: internal compiler error: unexpected panic

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.32.0-nightly (400c2bc5e 2018-11-27) running on x86_64-unknown-linux-gnu

note: compiler flags: -C debuginfo=2 -C incremental --crate-type lib

note: some of the compiler flags provided by cargo are hidden

error: Could not compile `embedded-sdmmc`.
warning: build failed, waiting for other jobs to finish...
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Some(NodeId(1090))`,
 right: `None`: free_scope: DefId(0/0:71 ~ embedded_sdmmc[93d1]::fat[0]::{{impl}}[4]) not recognized by the region scope tree for None / Some(DefId(0/0:78 ~ embedded_sdmmc[93d1]::fat[0]::{{impl}}[4]::lfn_contents[0]))', src/librustc/middle/region.rs:673:13
note: Run with `RUST_BACKTRACE=1` for a backtrace.

error: internal compiler error: unexpected panic

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

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.32.0-nightly (400c2bc5e 2018-11-27) running on x86_64-unknown-linux-gnu

note: compiler flags: -C debuginfo=2 -C incremental

note: some of the compiler flags provided by cargo are hidden

error: Could not compile `embedded-sdmmc`.

To learn more, run the command again with --verbose.

user@host:~/Documents/programming/embedded-sdmmc$ cargo version
cargo 1.31.0-beta (339d9f9c8 2018-11-16)

user@host:~/Documents/programming/embedded-sdmmc$ cargo +nightly version
cargo 1.32.0-nightly (b3d0b2e54 2018-11-15)

I'm using 2018 edition syntax, so I can only test on beta and nightly.

@Centril Centril added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Dec 3, 2018
@thejpster
Copy link
Contributor Author

Commenting out the lfn_contents() function in fat.rs makes the ICE go away.

The ICE occurs on a cargo build as well as a cargo test.

@thejpster
Copy link
Contributor Author

Replacing both instances of Self::FRAGMENT_LEN in the lfn_contents() function with the literal integer 13 makes the ICE go away.

@jonas-schievink jonas-schievink added C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jun 9, 2019
@jonas-schievink
Copy link
Contributor

jonas-schievink commented Jun 9, 2019

Still reproduces on 1.35.0 and nightly (rustc 1.37.0-nightly (991c719a1 2019-06-08)).

Click for backtrace

Backtrace:

stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:59
             at src/libstd/panicking.rs:197
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:211
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   6: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:381
   7: std::panicking::begin_panic_fmt
             at src/libstd/panicking.rs:336
   8: rustc::middle::region::ScopeTree::early_free_scope
   9: rustc::middle::free_region::RegionRelations::is_subregion_of
  10: rustc::infer::lexical_region_resolve::resolve
  11: rustc::infer::InferCtxt::resolve_regions_and_report_errors
  12: rustc_typeck::check::regionck::<impl rustc_typeck::check::FnCtxt>::regionck_expr
  13: rustc::ty::context::GlobalCtxt::enter_local
  14: rustc_typeck::check::typeck_tables_of
  15: rustc::ty::query::__query_compute::typeck_tables_of
  16: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::typeck_tables_of>::compute
  17: rustc::dep_graph::graph::DepGraph::with_task_impl
  18: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  19: rustc_mir::const_eval::const_eval_raw_provider
  20: rustc::ty::query::__query_compute::const_eval_raw
  21: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_raw>::compute
  22: rustc::dep_graph::graph::DepGraph::with_task_impl
  23: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  24: rustc_mir::const_eval::const_eval_provider
  25: rustc::ty::query::__query_compute::const_eval
  26: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval>::compute
  27: rustc::dep_graph::graph::DepGraph::with_task_impl
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  29: <rustc::traits::project::AssociatedTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_const
  30: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with
  31: <rustc::traits::project::AssociatedTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty
  32: <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter
  33: rustc::ty::fold::TypeFoldable::fold_with
  34: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with
  35: <rustc::traits::project::AssociatedTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty
  36: <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter
  37: rustc::ty::fold::TypeFoldable::fold_with
  38: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with
  39: <rustc::traits::project::AssociatedTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty
  40: <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter
  41: rustc::ty::fold::TypeFoldable::fold_with
  42: rustc::traits::project::normalize
  43: rustc::infer::InferCtxt::partially_normalize_associated_types_in
  44: rustc::ty::context::GlobalCtxt::enter_local
  45: rustc_typeck::check::wfcheck::check_associated_item
  46: rustc::ty::query::__query_compute::check_impl_item_well_formed
  47: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::check_impl_item_well_formed>::compute
  48: rustc::dep_graph::graph::DepGraph::with_task_impl
  49: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  50: <rustc_typeck::check::wfcheck::CheckTypeWellFormedVisitor as rustc::hir::itemlikevisit::ParItemLikeVisitor>::visit_impl_item
  51: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:87
  52: rustc_data_structures::sync::par_for_each_in
  53: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:87
  54: rustc::hir::Crate::par_visit_all_item_likes
  55: rustc::util::common::time
  56: rustc_typeck::check_crate
  57: rustc_interface::passes::analysis
  58: rustc::ty::query::__query_compute::analysis
  59: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::analysis>::compute
  60: rustc::dep_graph::graph::DepGraph::with_task_impl
  61: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  62: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  63: rustc_interface::passes::create_global_ctxt::{{closure}}
  64: rustc_interface::interface::run_compiler_in_existing_thread_pool
  65: std::thread::local::LocalKey<T>::with
  66: scoped_tls::ScopedKey<T>::set
  67: syntax::with_globals
query stack during panic:
#0 [typeck_tables_of] processing `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
#1 [const_eval_raw] const-evaluating `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
#2 [const_eval] const-evaluating + checking `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
#3 [check_impl_item_well_formed] processing `fat::OnDiskDirEntry::<'a>::lfn_contents`
#4 [analysis] running analysis passes on this crate
end of query stack

@pnkfelix pnkfelix added P-high High priority and removed I-nominated labels Jun 13, 2019
@pnkfelix
Copy link
Member

triage: P-high, removing nomination, assigning to self for initial investigation.

@pnkfelix pnkfelix self-assigned this Jun 13, 2019
@pnkfelix
Copy link
Member

pnkfelix commented Jun 14, 2019

Note: While I replicate the ICE as described on beta, I see a different ICE on nightly on this branch, namely:

error: internal compiler error: src/librustc_mir/borrow_check/nll/universal_regions.rs:741: cannot convert `ReEarlyBound(0, 'a)` to a region vid

For reference (in case it matters e.g. for a hypothetical backport) was injected between +nightly-2019-05-25 and +nightly-2019-05-26. Further bisection thanks to rustup-toolchain-install-master "pinpointed" the change to this rollup PR:

I'm pretty sure the change in behavior is due to PR #61118.

Click for stack trace
error: internal compiler error: src/librustc_mir/borrow_check/nll/universal_regions.rs:741: cannot convert `ReEarlyBound(0, 'a)` to a region vid

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:643:9
stack backtrace:
   0:     0x7ffb4696718b - backtrace::backtrace::libunwind::trace::h41595b2657878dbc
                               at /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
   1:     0x7ffb4696718b - backtrace::backtrace::trace_unsynchronized::h4efe511900bf5e12
                               at /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
   2:     0x7ffb4696718b - std::sys_common::backtrace::_print::h7275b63687b21f98
                               at src/libstd/sys_common/backtrace.rs:47
   3:     0x7ffb4696718b - std::sys_common::backtrace::print::h790c12384440cac4
                               at src/libstd/sys_common/backtrace.rs:36
   4:     0x7ffb4696718b - std::panicking::default_hook::{{closure}}::he6cba1bdf748f1c3
                               at src/libstd/panicking.rs:198
   5:     0x7ffb46966e8c - std::panicking::default_hook::h1296d9a476e7a9c2
                               at src/libstd/panicking.rs:212
   6:     0x7ffb446bb3f1 - rustc::util::common::panic_hook::ha2e96a0b919e5a1a
   7:     0x7ffb469679e9 - std::panicking::rust_panic_with_hook::h8d2408723e9a2bd4
                               at src/libstd/panicking.rs:479
   8:     0x7ffb433253ad - std::panicking::begin_panic::h234a5167f045a72d
   9:     0x7ffb4334544f - rustc_errors::Handler::bug::h3246723a0b2031e4
  10:     0x7ffb44420643 - rustc::util::bug::opt_span_bug_fmt::{{closure}}::hb8ea6d6e88ca54f4
  11:     0x7ffb444125da - rustc::ty::context::tls::with_opt::{{closure}}::h9f1dda041ea3d8ca
  12:     0x7ffb444124f5 - rustc::ty::context::tls::with_context_opt::h84ca529c2ea4a682
  13:     0x7ffb44412587 - rustc::ty::context::tls::with_opt::h875054e282c744c1
  14:     0x7ffb44420558 - rustc::util::bug::opt_span_bug_fmt::h24d0b9fdc514170c
  15:     0x7ffb444204c2 - rustc::util::bug::bug_fmt::hc0ddc16f6cc56100
  16:     0x7ffb459c72e2 - rustc_mir::borrow_check::nll::universal_regions::UniversalRegionIndices::to_region_vid::{{closure}}::h8f1191649fe952ee
  17:     0x7ffb45a9f866 - rustc_mir::borrow_check::nll::type_check::constraint_conversion::ConstraintConversion::convert_all::hff38c8376a2f82d5
  18:     0x7ffb45c4bd1c - rustc_mir::borrow_check::nll::type_check::TypeChecker::fully_perform_op::h78748fd6d92e387d
  19:     0x7ffb45c46a4b - rustc_mir::borrow_check::nll::type_check::type_check::hea7e4d9e23e5ba76
  20:     0x7ffb458bcd6f - rustc_mir::borrow_check::nll::compute_regions::h80ed7c7d15df620d
  21:     0x7ffb45976f83 - rustc_mir::borrow_check::do_mir_borrowck::hd7e464220fc5eca7
  22:     0x7ffb45cfe746 - rustc::ty::context::GlobalCtxt::enter_local::heaa8c87e8f8669e9
  23:     0x7ffb459765da - rustc_mir::borrow_check::mir_borrowck::hae96041a19836cd8
  24:     0x7ffb45954cb7 - rustc::ty::query::__query_compute::mir_borrowck::hc7e574fc48878e80
  25:     0x7ffb45c735a5 - rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_borrowck>::compute::h4a666fc8e52be0d8
  26:     0x7ffb459ed121 - rustc::dep_graph::graph::DepGraph::with_task_impl::hd0890e01d4a2bb3e
  27:     0x7ffb45cf234c - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query::hf2f4510df37bed60
  28:     0x7ffb45c73d25 - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::ensure_query::hf9d9f7fd3e34fbdf
  29:     0x7ffb458d1164 - rustc_mir::transform::optimized_mir::hcdb77108b4828931
  30:     0x7ffb4595507d - rustc::ty::query::__query_compute::optimized_mir::h2402952c578cb24c
  31:     0x7ffb45c7365d - rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::optimized_mir>::compute::ha863b92e11001b35
  32:     0x7ffb459f1497 - rustc::dep_graph::graph::DepGraph::with_task_impl::hf4b7b9c362d667eb
  33:     0x7ffb45c915ad - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query::h2ec66e6851178136
  34:     0x7ffb45aafff4 - rustc_mir::interpret::eval_context::InterpretCx<M>::load_mir::haeda8af7b0b03ee9
  35:     0x7ffb45c65bee - rustc_mir::const_eval::const_eval_raw_provider::hf339294a1d76412a
  36:     0x7ffb459553b1 - rustc::ty::query::__query_compute::const_eval_raw::hf79a48c673afa965
  37:     0x7ffb45c7370c - rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_raw>::compute::ha61cce162d227846
  38:     0x7ffb459ea072 - rustc::dep_graph::graph::DepGraph::with_task_impl::ha02743b6acac21ff
  39:     0x7ffb45c9dd2b - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query::h40523fc999af8bae
  40:     0x7ffb45c64e79 - rustc_mir::const_eval::const_eval_provider::h8ecd0d4acacbded6
  41:     0x7ffb442b17f8 - rustc::ty::query::__query_compute::const_eval::h1119198b82c92e58
  42:     0x7ffb4464f7bc - rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval>::compute::hbc876f0f390d6c25
  43:     0x7ffb4420173a - rustc::dep_graph::graph::DepGraph::with_task_impl::h35ad45147a002223
  44:     0x7ffb444796ab - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query::h0caac3b3a703e7cc
  45:     0x7ffb446a81e9 - <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_const::h09fb34e6e6e164e6
  46:     0x7ffb44415311 - rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with::h13b491c0c3eac0bf
  47:     0x7ffb446a7975 - <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty::h233440fce128939b
  48:     0x7ffb442c0659 - <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter::h590f39025e063bfa
  49:     0x7ffb443fa94c - rustc::ty::fold::TypeFoldable::fold_with::hb694e0d0547dc004
  50:     0x7ffb444154bd - rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with::h13b491c0c3eac0bf
  51:     0x7ffb446a7975 - <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty::h233440fce128939b
  52:     0x7ffb442c0659 - <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter::h590f39025e063bfa
  53:     0x7ffb443fa94c - rustc::ty::fold::TypeFoldable::fold_with::hb694e0d0547dc004
  54:     0x7ffb444152dd - rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable for &rustc::ty::TyS>::super_fold_with::h13b491c0c3eac0bf
  55:     0x7ffb446a7975 - <rustc::traits::project::AssocTypeNormalizer as rustc::ty::fold::TypeFolder>::fold_ty::h233440fce128939b
  56:     0x7ffb41701954 - <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter::he9a71a7d2a8e41a4
  57:     0x7ffb4155e9bc - rustc::ty::fold::TypeFoldable::fold_with::hb877186dcdde4a8a
  58:     0x7ffb4169fc64 - rustc::traits::project::normalize::hd55b9356461a2c54
  59:     0x7ffb414c0e58 - rustc_typeck::check::FnCtxt::normalize_associated_types_in::hd4ed4b1269b53182
  60:     0x7ffb4163c92d - rustc::ty::context::GlobalCtxt::enter_local::ha314227e251792e5
  61:     0x7ffb41713dd0 - rustc_typeck::check::wfcheck::check_associated_item::h7a5ca14b80bab58e
  62:     0x7ffb414e147e - rustc::ty::query::__query_compute::check_impl_item_well_formed::hca2766a1fa632057
  63:     0x7ffb415ab05d - rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::check_impl_item_well_formed>::compute::h04a3209f07ea56a6
  64:     0x7ffb4150f69b - rustc::dep_graph::graph::DepGraph::with_task_impl::h4963b94af07ea903
  65:     0x7ffb41620270 - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query::he56dc8058550bfc1
  66:     0x7ffb41716e67 - <rustc_typeck::check::wfcheck::CheckTypeWellFormedVisitor as rustc::hir::itemlikevisit::ParItemLikeVisitor>::visit_impl_item::h77cafc90c30a5ec3
  67:     0x7ffb469788da - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:82
  68:     0x7ffb41520dc9 - rustc_data_structures::sync::par_for_each_in::h550ca05f0ca541fa
  69:     0x7ffb469788da - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:82
  70:     0x7ffb416d8699 - rustc::hir::Crate::par_visit_all_item_likes::h2fa6afd0da02bfad
  71:     0x7ffb414e4c5d - rustc::util::common::time::he5d849132f13a9ee
  72:     0x7ffb416f8e08 - rustc_typeck::check_crate::h261fa85c0eefa2e6
  73:     0x7ffb46346855 - rustc_interface::passes::analysis::hd7064ffdb52b6f45
  74:     0x7ffb46cc71e6 - rustc::ty::query::__query_compute::analysis::hc63e7bbcf2ef51b7
  75:     0x7ffb46c32462 - rustc::dep_graph::graph::DepGraph::with_task_impl::h6ecc24de8ad82664
  76:     0x7ffb46c2a0ad - rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query::h3d879e5498479529
  77:     0x7ffb46c3b606 - rustc::ty::context::tls::enter_global::h429817b273ef3027
  78:     0x7ffb46c5a407 - rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}::h0a59fddc00963551
  79:     0x7ffb463a3b05 - rustc_interface::passes::create_global_ctxt::{{closure}}::h7a059b6cf199597d
  80:     0x7ffb46c5b7aa - rustc_interface::interface::run_compiler_in_existing_thread_pool::h35eddbfcfbbe0eb4
  81:     0x7ffb46ccd5f6 - std::thread::local::LocalKey<T>::with::hea85159711765771
  82:     0x7ffb46c65fb5 - scoped_tls::ScopedKey<T>::set::he08d6211f459724f
  83:     0x7ffb46c98ad4 - syntax::with_globals::h2c63be024f0c1f38
  84:     0x7ffb46cb789d - std::sys_common::backtrace::__rust_begin_short_backtrace::hfc7fb053a9ed90ec
  85:     0x7ffb469788da - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:82
  86:     0x7ffb46c436d9 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h0cd7d8fc1b0a39a3
  87:     0x7ffb4694aeef - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::he71721d2d956d451
                               at /rustc/0e4a56b4b04ea98bb16caada30cb2418dd06e250/src/liballoc/boxed.rs:746
  88:     0x7ffb469775b0 - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::he520045b8d28ce5c
                               at /rustc/0e4a56b4b04ea98bb16caada30cb2418dd06e250/src/liballoc/boxed.rs:746
  89:     0x7ffb469775b0 - std::sys_common::thread::start_thread::h2e98d1272dc6d74b
                               at src/libstd/sys_common/thread.rs:13
  90:     0x7ffb469775b0 - std::sys::unix::thread::Thread::new::thread_start::h18485805666ccd3c
                               at src/libstd/sys/unix/thread.rs:79
  91:     0x7ffb468bf58e - start_thread
                               at /usr/src/debug/glibc-2.28-60-g4d7af7815a/nptl/pthread_create.c:486
  92:     0x7ffb467de6a3 - clone
  93:                0x0 - <unknown>
query stack during panic:
#0 [mir_borrowck] processing `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
#1 [optimized_mir] processing `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
   --> src/fat.rs:276:56
    |
276 |     fn lfn_contents(&self) -> Option<(bool, u8, [char; Self::LFN_FRAGMENT_LEN])> {
    |                                                        ^^^^^^^^^^^^^^^^^^^^^^
#2 [const_eval_raw] const-evaluating `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
#3 [const_eval] const-evaluating + checking `fat::OnDiskDirEntry::<'a>::lfn_contents::{{constant}}#0`
#4 [check_impl_item_well_formed] processing `fat::OnDiskDirEntry::<'a>::lfn_contents`
#5 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

@pnkfelix
Copy link
Member

pnkfelix commented Jun 14, 2019

Okay here is reduced test case (play):

struct OnDiskDirEntry<'a> { _s: &'a usize }

impl<'a> OnDiskDirEntry<'a> {
    const LFN_FRAGMENT_LEN: usize = 2;

    fn lfn_contents(&self) -> [char; Self::LFN_FRAGMENT_LEN] { loop { } }
}

@pnkfelix
Copy link
Member

@thejpster another workaround, by the way, is to move the const LFN_FRAGMENT_LEN out of the impl (and then change the use to say LFN_FRAGMENT_LEN instead of Self::LFN_FRAGMENT_LEN)

@pnkfelix
Copy link
Member

And yet another workaround is to say [char; OnDiskDirEntry::LFN_FRAGMENT_LEN] instead of [char; Self::LFN_FRAGMENT_LEN] in the return type.

@pnkfelix pnkfelix changed the title ICE while running cargo test on embedded-sdmmc (uses 2018 edition) ICE from const item in lifetime-parametric impl Jul 3, 2019
@pnkfelix
Copy link
Member

I am taking a break for a few months and I wont be able to look at this; unassigning self.

@pnkfelix pnkfelix removed their assignment Jul 12, 2019
@estebank

This comment has been minimized.

@estebank estebank added A-const-generics Area: const generics (parameters and arguments) A-lifetimes Area: Lifetimes / regions labels Aug 5, 2019
@Centril Centril added requires-nightly This issue requires a nightly compiler in some way. F-const_generics `#![feature(const_generics)]` labels Aug 6, 2019
@jonas-schievink
Copy link
Contributor

Another occurrence in #63838:

pub struct Memory<'rom> {
    rom: &'rom [u8],
    ram: [u8; Self::SIZE],
}

impl<'rom> Memory<'rom> {
    pub const SIZE: usize = 0x8000;
}

JohnTitor added a commit to JohnTitor/rust that referenced this issue May 26, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 29, 2020
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue May 29, 2020
@JohnTitor
Copy link
Member

Triage: #56445 (comment) is now fixed in the latest nightly (I think it's fixed by #74051).
(And I've hidden comment as resolved to make the un-fixed ICEs easier to find.)

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 26, 2020
bors added a commit to rust-lang-ci/rust that referenced this issue Dec 27, 2020
…ination, r=varkor

stabilize `#![feature(min_const_generics)]` in 1.51

*A new Kind*
*A Sort long Prophesized*
*Once Fragile, now Eternal*

blocked on rust-lang#79073.

# Stabilization report

This is the stabilization report for `#![feature(min_const_generics)]` (tracking issue rust-lang#74878), a subset of `#![feature(const_generics)]` (tracking issue rust-lang#44580), based on rust-lang/rfcs#2000.

The [version target](https://forge.rust-lang.org/#current-release-versions) is ~~1.50 (2020-12-31 => beta, 2021-02-11 => stable)~~ 1.51 (2021-02-111 => beta, 2021-03-25 => stable).

This report is a collaborative effort of `@varkor,` `@shepmaster` and `@lcnr.`

## Summary

It is currently possible to parameterize functions, type aliases, types, traits and implementations by types and lifetimes.
With `#![feature(min_const_generics)]`, it becomes possible, in addition, to parameterize these by constants.

This is done using the syntax `const IDENT: Type` in the parameter listing. Unlike full const generics, `min_const_generics` is limited to parameterization by integers, and constants of type `char` or `bool`.

We already use `#![feature(min_const_generics)]` on stable to implement many common traits for arrays. See [the documentation](https://doc.rust-lang.org/nightly/std/primitive.array.html) for specific examples.

Generic const arguments, for now, are not permitted to involve computations depending on generic parameters. This means that const parameters may only be instantiated using either:

1. const expressions that do not depend on any generic parameters, e.g. `{ foo() + 1 }`, where `foo` is a `const fn`
1. standalone const parameters, e.g. `{N}`

### Example

```rust
#![feature(min_const_generics)]

trait Foo<const N: usize> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]);
}

struct Bar<T, const N: usize> {
    inner: [T; N],
}

impl<const N: usize> Foo<N> for Bar<u8, N> {
    fn method<const M: usize>(&mut self, arr: [[u8; M]; N]) {
        for (elem, s) in self.inner.iter_mut().zip(arr.iter()) {
            for &x in s {
                *elem &= x;
            }
        }
    }
}

fn function<const N: u16>() -> u16 {
    // Const parameters can be used freely inside of functions.
    (N + 1) / 2 * N
}

fn main() {
    let mut bar = Bar { inner: [0xff; 3] };
    // This infers the value of `M` from the type of the function argument.
    bar.method([[0b11_00, 0b01_00], [0b00_11, 0b00_01], [0b11_00, 0b00_11]]);
    assert_eq!(bar.inner, [0b01_00, 0b00_01, 0b00_00]);

    // You can also explicitly specify the value of `N`.
    assert_eq!(function::<17>(), 153);
}
```

## Motivation

Rust has the built-in array type, which is parametric over a constant. Without const generics, this type can be quite cumbersome to use as it is not possible to generically implement a trait for arrays of different lengths. For example, this meant that, for a long time, the standard library only contained trait implementations for arrays up to a length of 32. This restriction has since been lifted through the use of const generics.

Const parameters allow users to naturally specify variants of a generic type which are more naturally parameterized by values, rather than by types. For example, using const generics, many of the uses of the crate [typenum](https://crates.io/crates/typenum) may now be replaced with const parameters, improving compilation time as well as code readability and diagnostics.

The subset described by `min_const_generics` is self-contained, but extensive enough to help with the most frequent issues: implementing traits for arrays and using arbitrarily-sized arrays inside of other types. Furthermore, it extends naturally to full `const_generics` once the remaining design and implementation questions have been resolved.

## In-depth feature description

### Declaring const parameters

*Const parameters* are allowed in all places where types and lifetimes are supported. They use the syntax `const IDENT: Type`. Currently, const parameters must be declared after lifetime and type parameters. Their scope is equal to the scope of other generic parameters. They live in the value namespace.

`Type` must be one of `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize`, `char` and `bool`. This restriction is implemented in two places:

1. during name resolution, where we forbid generic parameters
1. during well-formedness checking, where we only allow the types listed above

The updated syntax of parameter listings is:

```
GenericParams:
    (OuterAttr* LifetimeParam),* (OuterAttr* TypeParam),* (OuterAttr* ConstParam),*

OuterAttr: '#[' ... ']'
LifetimeParam: ...
TypeParam: ...
ConstParam: 'const' IDENT ':' Type
```

Unlike type and lifetime parameters, const parameters of types can be used without being mentioned inside of a parameterized type because const parameters do not have issues concerning variance. This means that the following types are allowed:

```rust
struct Foo<const N: usize>;
enum Bar<const M: usize> { A, B }
```

### Const arguments

Const parameters are instantiated using *const arguments*. Any concrete const expression or const parameter as a standalone argument can be used. When applying an expression as const parameter, most expressions must be contained within a block, with two exceptions:

1. literals and single-segment path expressions
1. array lengths

This syntactic restriction is necessary to avoid ambiguity, or requiring infinite lookahead when parsing an expression as a generic argument.

In the cases where a generic argument could be resolved as either a type or const argument, we always interpret it as a type. This causes the following test to fail:

```rust
type N = u32;
struct Foo<const N: usize>;
fn foo<const N: usize>() -> Foo<N> { todo!() } // ERR
```

To circumvent this, the user may wrap the const parameter with braces, at which point it is unambiguously accepted.

```rust
type N = u32;
struct Foo<const N: usize>;
fn bar<const N: usize>() -> Foo<{ N }> { todo!() } // ok
```

Operations depending on generic parameters are **not** allowed, which is enforced during well-formedness checking. Allowing generic unevaluated constants would require a way to check if they would always evaluate successfully to prevent errors that are not caught at declaration time. This ability forms part of `#![feature(const_evaluatable_checked)]`, which is not yet being stabilised.

Since we are not yet stabilizing `#![feature(lazy_normalization_consts)]`, we must not supply the parent generics to anonymous constants except for repeat expressions. Doing so can cause cycle errors for arrays used in `where`-bounds. Not supplying the parent generics can however lead to ICEs occurring before well-formedness checking when trying to use a generic parameter. See rust-lang#56445 for details.

Since we expect cases like this to occur more frequently once `min_const_generics` is stabilized, we have chosen to forbid generic parameters in anonymous constants during name resolution. While this changes the ICE in the situation above to an ordinary error, this is theoretically a breaking change, as early-bound lifetimes were previously permitted in repeat expressions but now are disallowed, causing the following snippet to break:

```rust
fn late_bound<'a>() {
    let _ = [0; {
        let _: &'a (); // ICE ==> ERR
        3
    }];
}

fn early_bound<'a>() where &'a (): Sized {
    let _ = [0; {
        let _: &'a (); // ok ==> ERR
        3
    }];
}
```

### Using const parameters

Const parameters can be used almost everywhere ordinary constants are allowed, except that they may not be used in the construction of consts, statics, functions, or types inside a function body and are subject to the generic argument restrictions mentioned above.

Expressions containing const parameters are eligible for promotion:

```rust
fn test<const N: usize>() -> &'static usize {
    &(3 + N)
}
```

### Symbol mangling

See the [Rust symbol name mangling RFC](https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html) for an overview. Generic const parameters take the form `K[type][value]` when the value is known, or `Kp` where the value is not known, where:
- `[type]` is any integral type, `bool`, or `char`.
- `[value]` is the unsigned hex value for integers, preceded by `n` when negative; is `0` or `1` for `bool`; is the hex value for `char`.

### Exhaustiveness checking

We do not check the exhaustiveness of impls, meaning that the following example does **not** compile:

```rust
struct Foo<const B: bool>;
trait Bar {}
impl Bar for Foo<true> {}
impl Bar for Foo<false> {}

fn needs_bar(_: impl Bar) {}
fn generic<const B: bool>() {
    let v = Foo::<B>;
    needs_bar(v);
}
```

### Type inference

The value of const parameters can be inferred during typeck. One interesting case is the length of generic arrays, which can also be inferred from patterns (implemented in rust-lang#70562). Practical usage of this can be seen in rust-lang#76825.

### Equality of constants

`#![feature(min_const_generics)]` only permits generic parameters to be used as standalone generic arguments. We compare two parameters to be equal if they are literally the same generic parameter.

### Associated constants

Associated constants can use const parameters without restriction, see rust-lang#79135 (comment) for more details.

## Future work

As this is a limited subset of rust-lang/rfcs#2000, there are quite a few extensions we will be looking into next.

### Lazy normalization of constants

Stabilizing `#![feature(lazy_normalization_consts)]` (tracking issue rust-lang#72219) will remove some special cases that are currently necessary for `min_const_generics`, and unblocks operations on const parameters.

### Relaxing ordering requirements between const and type parameters

We currently restrict the order of generic parameters so that types must come before consts. We could relax this, as is currently done with `const_generics`. Without this it is not possible to use both type defaults and const parameters at the same time.

Unrestricting the order will require us to improve some diagnostics that expect there to be a strict order between type and const parameters.

### Allowing more parameter types

We would like to support const parameters of more types, especially`&str` and user-defined types. Both are blocked on [valtrees]. There are also open questions regarding the design of `structural_match` concerning the latter. Supporting generic const parameter types such as `struct Foo<T, const N: T>` will be a lot harder and is unlikely to be implemented in the near future.

### Default values of const parameters

We do not yet support default values for const parameters. There is work in progress to enable this on nightly (see rust-lang#75384).

### Generic const operations

With `#![feature(min_const_generics)]`, only concrete const expressions and parameters as standalone arguments are allowed in types and repeat expressions. However, supporting generic const operations, such as `N + 1` or `std::mem::size_of::<T>()` is highly desirable. This feature is in early development under `#![feature(const_evaluatable_checked)]`.

## Implementation history

Many people have contributed to the design and implementation of const generics over the last three years. See rust-lang#44580 (comment) for a summary. Once again thank you to everybody who helped out here!

[valtrees]: rust-lang#72396

---

r? `@varkor`
@JohnTitor
Copy link
Member

Triage:
The reduced snippet (#56445 (comment)) and #56445 (comment) are no longer ICE with the latest nightly: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=2d74015d14721b961d717ac11c343a0c

@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
@varkor varkor added the const-generics-fixed-by-const_generics A bug that has been fixed once `const_generics` is enabled. label Dec 30, 2020
@oli-obk oli-obk added E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. and removed P-high High priority E-hard Call for participation: Hard difficulty. Experience needed to fix: A lot. labels Dec 31, 2020
@sjakobi
Copy link
Contributor

sjakobi commented Mar 27, 2021

@rustbot claim

JohnTitor added a commit to JohnTitor/rust that referenced this issue Mar 27, 2021
bors added a commit to rust-lang-ci/rust that referenced this issue Mar 27, 2021
Rollup of 10 pull requests

Successful merges:

 - rust-lang#79399 (Use detailed and shorter fs error explaination)
 - rust-lang#83348 (format macro argument parsing fix)
 - rust-lang#83462 (ExitStatus: print "exit status: {}" rather than "exit code: {}" on unix)
 - rust-lang#83526 (lazily calls some fns)
 - rust-lang#83558 (Use DebugStruct::finish_non_exhaustive() in std.)
 - rust-lang#83559 (Fix Debug implementation for RwLock{Read,Write}Guard.)
 - rust-lang#83560 (Derive Debug for io::Chain instead of manually implementing it.)
 - rust-lang#83561 (Improve Debug implementations of Mutex and RwLock.)
 - rust-lang#83567 (Update rustup cross-compilation docs link)
 - rust-lang#83569 (Add regression tests for rust-lang#56445)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors closed this as completed in 0927580 Mar 27, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) A-lazy-normalization Area: Lazy normalization (tracking issue: #60471) A-lifetimes Area: Lifetimes / regions C-bug Category: This is a bug. const-generics-fixed-by-const_generics A bug that has been fixed once `const_generics` is enabled. D-confusing Diagnostics: Confusing error or lint that should be reworked. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. 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)]` 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

Successfully merging a pull request may close this issue.