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

Inferring const parameters to wrapper type causes rustc to panic. #92626

Closed
nzentzis opened this issue Jan 6, 2022 · 3 comments · Fixed by #92640
Closed

Inferring const parameters to wrapper type causes rustc to panic. #92626

nzentzis opened this issue Jan 6, 2022 · 3 comments · Fixed by #92640
Assignees
Labels
C-bug Category: This is a bug. 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

@nzentzis
Copy link

nzentzis commented Jan 6, 2022

Code

Playground link

struct Test<T, const N: usize>([T; N]);

impl<T: Copy+Default, const N: usize> Default for Test<T, N> {
    fn default() -> Self {
        Self([T::default(); N])
    }
}

impl<T, const N: usize> std::ops::Deref for Test<T, N> {
    type Target = [T; N];
    
    fn deref(&self) -> &[T; N] {
        &self.0
    }
}

impl<T, const N: usize> std::ops::DerefMut for Test<T, N> {
    fn deref_mut(&mut self) -> &mut [T; N] {
        &mut self.0
    }
}

fn test() -> Test<u64, 16> {
    let mut out = Test::default();
    for val in out.iter_mut() {
        *val = 0u64;
    }
    
    out
}

Removing the const generic parameter N or annotating out inside test with an explicit type (e.g. let mut out: Test<u64, 16> = Test::default();) avoids the compiler panic.

Meta

Reproduces on stable, beta, and the nightly version available on the Playground. Backtrace and error output information are copied from Playground output.

Error output

   Compiling playground v0.0.1 (/playground)
error[E0601]: `main` function not found in crate `playground`
  --> src/main.rs:1:1
   |
1  | / struct Test<T, const N: usize>([T; N]);
2  | |
3  | | impl<T: Copy+Default, const N: usize> Default for Test<T, N> {
4  | |     fn default() -> Self {
...  |
29 | |     out
30 | | }
   | |_^ consider adding a `main` function to `src/main.rs`

thread 'rustc' panicked at 'index out of bounds: the len is 13 but the index is 16', /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/ena-0.14.0/src/snapshot_vec.rs:199:10
stack backtrace:
   0: rust_begin_unwind
             at /rustc/f1ce0e6a00593493a12e0e3662119786c761f375/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/f1ce0e6a00593493a12e0e3662119786c761f375/library/core/src/panicking.rs:107:14
   2: core::panicking::panic_bounds_check
             at /rustc/f1ce0e6a00593493a12e0e3662119786c761f375/library/core/src/panicking.rs:75:5
   3: <rustc_infer::infer::equate::Equate as rustc_middle::ty::relate::TypeRelation>::relate::<&rustc_middle::ty::TyS>
   4: rustc_middle::ty::relate::super_relate_tys::<rustc_infer::infer::equate::Equate>
   5: <rustc_infer::infer::equate::Equate as rustc_middle::ty::relate::TypeRelation>::relate::<&rustc_middle::ty::TyS>
   6: <rustc_infer::infer::sub::Sub as rustc_middle::ty::relate::TypeRelation>::relate_with_variance::<&rustc_middle::ty::TyS>
   7: rustc_middle::ty::relate::super_relate_tys::<rustc_infer::infer::sub::Sub>
   8: <rustc_infer::infer::sub::Sub as rustc_middle::ty::relate::TypeRelation>::tys
   9: <rustc_infer::infer::at::At>::sup::<&rustc_middle::ty::TyS>
  10: <rustc_typeck::check::method::confirm::ConfirmContext>::confirm
  11: <rustc_typeck::check::fn_ctxt::FnCtxt>::lookup_method
  12: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  13: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  14: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_argument_types
  15: <rustc_typeck::check::fn_ctxt::FnCtxt>::confirm_builtin_call
  16: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_call
  17: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  18: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  19: <rustc_typeck::check::fn_ctxt::FnCtxt>::demand_scrutinee_type
  20: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_match
  21: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  22: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  23: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  24: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_stmt
  25: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_block_with_expected
  26: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  27: rustc_typeck::check::check::check_fn
  28: <rustc_infer::infer::InferCtxtBuilder>::enter::<&rustc_middle::ty::context::TypeckResults, <rustc_typeck::check::inherited::InheritedBuilder>::enter<rustc_typeck::check::typeck_with_fallback<rustc_typeck::check::typeck::{closure#0}>::{closure#1}, &rustc_middle::ty::context::TypeckResults>::{closure#0}>
  29: rustc_typeck::check::typeck
  30: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>>
  31: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck
  32: <rustc_middle::hir::map::Map>::par_body_owners::<rustc_typeck::check::typeck_item_bodies::{closure#0}>
  33: rustc_typeck::check::typeck_item_bodies
  34: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), ()>>
  35: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::typeck_item_bodies, rustc_query_impl::plumbing::QueryCtxt>
  36: <rustc_session::session::Session>::time::<(), rustc_typeck::check_crate::{closure#7}>
  37: rustc_typeck::check_crate
  38: rustc_interface::passes::analysis
  39: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), core::result::Result<(), rustc_errors::ErrorReported>>>
  40: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
  41: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorReported>>
  42: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
  43: rustc_interface::interface::create_compiler_and_run::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>
  44: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose 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/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.59.0-nightly (f1ce0e6a0 2022-01-05) running on x86_64-unknown-linux-gnu

note: compiler flags: -C embed-bitcode=no -C codegen-units=1 -C debuginfo=2 --crate-type bin

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

query stack during panic:
#0 [typeck] type-checking `test`
#1 [typeck_item_bodies] type-checking all item bodies
#2 [analysis] running analysis passes on this crate
end of query stack
For more information about this error, try `rustc --explain E0601`.
error: could not compile `playground` due to previous error
Backtrace

thread 'rustc' panicked at 'index out of bounds: the len is 13 but the index is 16', /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/ena-0.14.0/src/snapshot_vec.rs:199:10
stack backtrace:
   0: rust_begin_unwind
             at /rustc/f1ce0e6a00593493a12e0e3662119786c761f375/library/std/src/panicking.rs:498:5
   1: core::panicking::panic_fmt
             at /rustc/f1ce0e6a00593493a12e0e3662119786c761f375/library/core/src/panicking.rs:107:14
   2: core::panicking::panic_bounds_check
             at /rustc/f1ce0e6a00593493a12e0e3662119786c761f375/library/core/src/panicking.rs:75:5
   3: <rustc_infer::infer::equate::Equate as rustc_middle::ty::relate::TypeRelation>::relate::<&rustc_middle::ty::TyS>
   4: rustc_middle::ty::relate::super_relate_tys::<rustc_infer::infer::equate::Equate>
   5: <rustc_infer::infer::equate::Equate as rustc_middle::ty::relate::TypeRelation>::relate::<&rustc_middle::ty::TyS>
   6: <rustc_infer::infer::sub::Sub as rustc_middle::ty::relate::TypeRelation>::relate_with_variance::<&rustc_middle::ty::TyS>
   7: rustc_middle::ty::relate::super_relate_tys::<rustc_infer::infer::sub::Sub>
   8: <rustc_infer::infer::sub::Sub as rustc_middle::ty::relate::TypeRelation>::tys
   9: <rustc_infer::infer::at::At>::sup::<&rustc_middle::ty::TyS>
  10: <rustc_typeck::check::method::confirm::ConfirmContext>::confirm
  11: <rustc_typeck::check::fn_ctxt::FnCtxt>::lookup_method
  12: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  13: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  14: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_argument_types
  15: <rustc_typeck::check::fn_ctxt::FnCtxt>::confirm_builtin_call
  16: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_call
  17: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  18: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  19: <rustc_typeck::check::fn_ctxt::FnCtxt>::demand_scrutinee_type
  20: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_match
  21: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_kind
  22: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  23: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  24: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_stmt
  25: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_block_with_expected
  26: <rustc_typeck::check::fn_ctxt::FnCtxt>::check_expr_with_expectation_and_args
  27: rustc_typeck::check::check::check_fn
  28: <rustc_infer::infer::InferCtxtBuilder>::enter::<&rustc_middle::ty::context::TypeckResults, <rustc_typeck::check::inherited::InheritedBuilder>::enter<rustc_typeck::check::typeck_with_fallback<rustc_typeck::check::typeck::{closure#0}>::{closure#1}, &rustc_middle::ty::context::TypeckResults>::{closure#0}>
  29: rustc_typeck::check::typeck
  30: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<rustc_span::def_id::LocalDefId, &rustc_middle::ty::context::TypeckResults>>
  31: <rustc_query_impl::Queries as rustc_middle::ty::query::QueryEngine>::typeck
  32: <rustc_middle::hir::map::Map>::par_body_owners::<rustc_typeck::check::typeck_item_bodies::{closure#0}>
  33: rustc_typeck::check::typeck_item_bodies
  34: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), ()>>
  35: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::typeck_item_bodies, rustc_query_impl::plumbing::QueryCtxt>
  36: <rustc_session::session::Session>::time::<(), rustc_typeck::check_crate::{closure#7}>
  37: rustc_typeck::check_crate
  38: rustc_interface::passes::analysis
  39: rustc_query_system::query::plumbing::try_execute_query::<rustc_query_impl::plumbing::QueryCtxt, rustc_query_system::query::caches::DefaultCache<(), core::result::Result<(), rustc_errors::ErrorReported>>>
  40: rustc_query_system::query::plumbing::get_query::<rustc_query_impl::queries::analysis, rustc_query_impl::plumbing::QueryCtxt>
  41: <rustc_interface::interface::Compiler>::enter::<rustc_driver::run_compiler::{closure#1}::{closure#2}, core::result::Result<core::option::Option<rustc_interface::queries::Linker>, rustc_errors::ErrorReported>>
  42: rustc_span::with_source_map::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_interface::interface::create_compiler_and_run<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#1}>
  43: rustc_interface::interface::create_compiler_and_run::<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>
  44: <scoped_tls::ScopedKey<rustc_span::SessionGlobals>>::set::<rustc_interface::util::setup_callbacks_and_run_in_thread_pool_with_globals<rustc_interface::interface::run_compiler<core::result::Result<(), rustc_errors::ErrorReported>, rustc_driver::run_compiler::{closure#1}>::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>::{closure#0}::{closure#0}, core::result::Result<(), rustc_errors::ErrorReported>>
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

@nzentzis nzentzis 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 Jan 6, 2022
@compiler-errors
Copy link
Member

So if I understand this ICE correctly, this is caused by an escaping type inference var that should've been rolled back during a InferCtxt::probe.

I'll take a stab at this, otherwise I'll give it up if I can't get to a solution.

@rustbot claim

@compiler-errors
Copy link
Member

compiler-errors commented Jan 7, 2022

Minimized slightly.

#![allow(unreachable_code)]

struct Test<T, const N: usize>([T; N]);

impl<T, const N: usize> std::ops::Deref for Test<T, N> {
    type Target = [T; N];
    
    fn deref(&self) -> &[T; N] {
        &self.0
    }
}

fn test() {
    let mut out = Test(todo!());
    let blah = out.len();
}

@compiler-errors
Copy link
Member

compiler-errors commented Jan 7, 2022

So I think I understand the essence of the issue here.

So when we canonicalize a const variable then substitute it back with a new variable, we lose its type information.

The consequence of this is that we create more inference variables during the probe part of method lookup than during the confirm part -- and currently this code depends on the number of new inference variables created during those steps to be equal, otherwise we refer to an inference variable that doesn't exist...

I've got a fix for this issue, but seems like still one region variable that shouldn't be there is leaking...

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. 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
3 participants