Skip to content

reordering type parameters causes const generics ICE #69970

New issue

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

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

Already on GitHub? # to your account

Closed
Nugine opened this issue Mar 13, 2020 · 4 comments · Fixed by #70032
Closed

reordering type parameters causes const generics ICE #69970

Nugine opened this issue Mar 13, 2020 · 4 comments · Fixed by #70032
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. 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

@Nugine
Copy link
Contributor

Nugine commented Mar 13, 2020

Code

#![feature(const_generics)]

struct Bad<const N: usize, T> {
    arr: [u8; { N }],
    another: T,
}

// struct Good<T, const N: usize> {
//     arr: [u8; { N }],
//     another: T,
// }

fn main() {}

Meta

rustc +nightly --version --verbose:

rustc 1.43.0-nightly (c20d7eecb 2020-03-11)
binary: rustc
commit-hash: c20d7eecbc0928b57da8fe30b2ef8528e2bdd5be
commit-date: 2020-03-11
host: x86_64-unknown-linux-gnu
release: 1.43.0-nightly
LLVM version: 9.0

Error output

error: type parameters must be declared prior to const parameters
 --> src/main.rs:3:28
  |
3 | struct Bad<const N: usize, T> {
  |           -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`

warning: the feature `const_generics` is incomplete and may cause the compiler to crash
 --> src/main.rs:1:12
  |
1 | #![feature(const_generics)]
  |            ^^^^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default

thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1', src/librustc_typeck/collect.rs:1318:54
note: run with `RUST_BACKTRACE=1` environment variable to display 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.43.0-nightly (c20d7eecb 2020-03-11) running on x86_64-unknown-linux-gnu

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

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

error: aborting due to previous error
Backtrace

error: type parameters must be declared prior to const parameters
 --> src/main.rs:3:28
  |
3 | struct Bad<const N: usize, T> {
  |           -----------------^- help: reorder the parameters: lifetimes, then types, then consts: `<T, const N: usize>`

warning: the feature `const_generics` is incomplete and may cause the compiler to crash
 --> src/main.rs:1:12
  |
1 | #![feature(const_generics)]
  |            ^^^^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default

thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1', src/librustc_typeck/collect.rs:1318:54
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/github.heygears.com-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/github.heygears.com-1ecc6299db9ec823/backtrace-0.3.44/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:1063
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1426
   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:204
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:224
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:474
  12: rust_begin_unwind
             at src/libstd/panicking.rs:378
  13: core::panicking::panic_fmt
             at src/libcore/panicking.rs:111
  14: core::panicking::panic_bounds_check
             at src/libcore/panicking.rs:69
  15: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
  16: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::spec_extend
  17: rustc_typeck::collect::generics_of
  18: rustc::ty::query::__query_compute::generics_of
  19: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::generics_of>::compute
  20: rustc::dep_graph::graph::DepGraph::with_task_impl
  21: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  22: <rustc_typeck::collect::CollectItemTypesVisitor as rustc_hir::intravisit::Visitor>::visit_item
  23: rustc::hir::map::Map::visit_item_likes_in_module
  24: rustc_typeck::collect::collect_mod_item_types
  25: rustc::ty::query::__query_compute::collect_mod_item_types
  26: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::collect_mod_item_types>::compute
  27: rustc::dep_graph::graph::DepGraph::with_task_impl
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  29: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::ensure_query
  30: rustc_typeck::check_crate
  31: rustc_interface::passes::analysis
  32: rustc::ty::query::__query_compute::analysis
  33: rustc::dep_graph::graph::DepGraph::with_task_impl
  34: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  35: rustc::ty::context::tls::enter_global
  36: rustc_interface::interface::run_compiler_in_existing_thread_pool
  37: scoped_tls::ScopedKey<T>::set
  38: rustc_ast::attr::with_globals
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/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.43.0-nightly (c20d7eecb 2020-03-11) running on x86_64-unknown-linux-gnu

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

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

query stack during panic:
#0 [generics_of] processing `Bad`
#1 [collect_mod_item_types] collecting item types in top-level module
#2 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

@Nugine Nugine 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 Mar 13, 2020
@JohnTitor JohnTitor added the A-const-generics Area: const generics (parameters and arguments) label Mar 13, 2020
@JohnTitor
Copy link
Member

It doesn't require feature flag.

@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Mar 13, 2020
@Centril Centril added the F-const_generics `#![feature(const_generics)]` label Mar 13, 2020
@lcnr
Copy link
Contributor

lcnr commented Mar 15, 2020

I am currently working on this

@lcnr
Copy link
Contributor

lcnr commented Mar 15, 2020

@varkor, my first idea was to fix this ICE locally by offsetting i in line 1318 for each wrongly placed const param.

// Now create the real type and const parameters.
let type_start = own_start - has_self as u32 + params.len() as u32;
let mut i = 0;
params.extend(ast_generics.params.iter().filter_map(|param| {
let kind = match param.kind {
GenericParamKind::Type { ref default, synthetic, .. } => {
if !allow_defaults && default.is_some() {
if !tcx.features().default_type_parameter_fallback {
tcx.struct_span_lint_hir(
lint::builtin::INVALID_TYPE_PARAM_DEFAULT,
param.hir_id,
param.span,
|lint| {
lint.build(
"defaults for type parameters are only allowed in \
`struct`, `enum`, `type`, or `trait` definitions.",
)
.emit();
},
);
}
}
ty::GenericParamDefKind::Type {
has_default: default.is_some(),
object_lifetime_default: object_lifetime_defaults
.as_ref()
.map_or(rl::Set1::Empty, |o| o[i]),

This only moves the error further back.

fn ty_for_param(&self, p: ty::ParamTy, source_ty: Ty<'tcx>) -> Ty<'tcx> {
// Look up the type in the substitutions. It really should be in there.
let opt_ty = self.substs.get(p.index as usize).map(|k| k.unpack());
let ty = match opt_ty {
Some(GenericArgKind::Type(ty)) => ty,
Some(kind) => {
let span = self.span.unwrap_or(DUMMY_SP);
span_bug!(
span,
"expected type for `{:?}` ({:?}/{}) but found {:?} \
when substituting (root type={:?}) substs={:?}",
p,
source_ty,
p.index,
kind,
self.root_ty,
self.substs,
);
}

I currently think that it would be best to actually fix the param order if validate_generic_param_order order fails.

fn validate_generic_param_order<'a>(
sess: &Session,
handler: &rustc_errors::Handler,
generics: impl Iterator<Item = (ParamKindOrd, Option<&'a [GenericBound]>, Span, Option<String>)>,
span: Span,
) {

Is this a good approach?

And how should this be done, as validate_generic_param_order is used in AstVisitor::visit_generics, which only receives an immutable reference to Generics.

@varkor
Copy link
Member

varkor commented Mar 15, 2020

I think the right fix for this would be to make sure we can handle generic parameters in any order — there's no technical reason the parameters should be in a fixed order; it's just historical. This would involve doing what you started with, and fixing each problem in turn. However, I don't know how many things still rely on this order, so it could be an involved task.

For a shorter-term fix, we could just make sure that generics are sorted if they're in the wrong order. We could probably do this in generics_of and sort the ast_generics.params before creating the ty::GenericParamDef. This might be more pragmatic, though we should leave a FIXME to address later if we do this.

Thanks for looking into this @lcnr!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-const-generics Area: const generics (parameters and arguments) C-bug Category: This is a bug. 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.

6 participants