Rust-clippy: ICE on sized-chunks crate

Created on 20 May 2019  路  11Comments  路  Source: rust-lang/rust-clippy

The sized-chunks v0.3.0 crate is causing an ICE in latest clippy. I do not know where to start debugging this.

clippy 0.0.212 (60a609a 2019-05-17)
error: internal compiler error: src/librustc/ty/subst.rs:569: type parameter `T/#1` (T/1) out of range when substituting (root type=Some(T)) substs=[T]

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:572:9
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose 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::begin_panic
   7: rustc_errors::Handler::span_bug
   8: rustc::util::bug::opt_span_bug_fmt::{{closure}}
   9: rustc::ty::context::tls::with_opt::{{closure}}
  10: rustc::ty::context::tls::with_context_opt
  11: rustc::ty::context::tls::with_opt
  12: rustc::util::bug::opt_span_bug_fmt
  13: rustc::util::bug::span_bug_fmt
  14: <rustc::ty::subst::SubstFolder as rustc::ty::fold::TypeFolder>::fold_ty
  15: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &mut F>::call_once
  16: <smallvec::SmallVec<A> as core::iter::traits::collect::FromIterator<<A as smallvec::Array>::Item>>::from_iter
  17: rustc::ty::fold::TypeFoldable::fold_with
  18: rustc::traits::codegen::<impl rustc::ty::context::TyCtxt>::subst_and_normalize_erasing_regions
  19: rustc_mir::interpret::eval_context::InterpretCx<M>::resolve
  20: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::run
  21: rustc_mir::const_eval::eval_body_using_ecx
  22: rustc_mir::const_eval::const_eval_raw_provider
  23: rustc::ty::query::__query_compute::const_eval_raw
  24: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_raw>::compute
  25: rustc::dep_graph::graph::DepGraph::with_task_impl
  26: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  27: rustc_mir::const_eval::const_eval_provider
  28: rustc::ty::query::__query_compute::const_eval
  29: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval>::compute
  30: rustc::dep_graph::graph::DepGraph::with_task_impl
  31: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  32: clippy_lints::consts::ConstEvalLateContext::expr
  33: clippy_lints::consts::ConstEvalLateContext::expr
  34: clippy_lints::consts::constant_simple
  35: clippy_lints::utils::hir_utils::SpanlessEq::eq_expr
  36: <clippy_lints::eq_op::EqOp as rustc::lint::LateLintPass>::check_expr
  37: <rustc::lint::context::LateLintPassObjects as rustc::lint::LateLintPass>::check_expr
  38: <rustc::lint::context::LateContextAndPass<T> as rustc::hir::intravisit::Visitor>::visit_expr
  39: <rustc::lint::context::LateContextAndPass<T> as rustc::hir::intravisit::Visitor>::visit_nested_body
  40: rustc::hir::intravisit::Visitor::visit_nested_impl_item
  41: rustc::hir::intravisit::walk_item
  42: rustc::hir::intravisit::Visitor::visit_nested_item
  43: rustc::hir::intravisit::walk_item
  44: rustc::hir::intravisit::Visitor::visit_nested_item
  45: rustc::hir::intravisit::walk_crate
  46: rustc::lint::context::late_lint_pass_crate
  47: rustc::lint::context::late_lint_crate
  48: rustc::util::common::time
  49: rustc::util::common::time
  50: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:85
  51: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  52: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:85
  53: rustc_interface::passes::analysis::{{closure}}
  54: rustc::util::common::time
  55: rustc_interface::passes::analysis
  56: rustc::ty::query::__query_compute::analysis
  57: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::analysis>::compute
  58: rustc::dep_graph::graph::DepGraph::with_task_impl
  59: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  60: rustc::ty::context::tls::enter_global
  61: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  62: rustc_interface::passes::create_global_ctxt::{{closure}}
  63: rustc_interface::interface::run_compiler_in_existing_thread_pool
  64: std::thread::local::LocalKey<T>::with
  65: scoped_tls::ScopedKey<T>::set
  66: syntax::with_globals
query stack during panic:
#0 [const_eval_raw] const-evaluating `inline_array::InlineArray::<A, T>::HOST_SIZE`
#1 [const_eval] const-evaluating + checking `inline_array::InlineArray::<A, T>::HOST_SIZE`
#2 [analysis] running analysis passes on this crate
end of query stack
L-crash P-needs-test

Most helpful comment

I've found the problem, it is in rustc. Currently trying to create a rustc-only ICE

All 11 comments

Going to investigate this now and try to get a minimal repro case.

Minimal repro:

use std::mem::{self};

pub struct Foo<A, B>(A, B);

impl<A, B> Foo<A, B> {
    const HOST_SIZE: usize = mem::size_of::<B>();

    pub fn crash() -> bool {
        Self::HOST_SIZE == 0
    }
}

The conditional triggers the crash. It crashes here, called from the eq_op lint:

https://github.com/rust-lang/rust-clippy/blob/2cc23a5b18de3726de81202802fc459559342215/clippy_lints/src/consts.rs#L342

Unfortunately I ran out of time for today, so if someone want's to continue with this, feel free.

cc @oli-obk

Managed to further reduce the example (updated above) and got some initial debug output of the data that causes the crash. Unfortunately there's nothing that stands out as outright wrong so far:

[clippy_lints/src/eq_op.rs:58] left = expr(HirId { owner: DefIndex(24), local_id: 4 }: <Self>::HOST_SIZE)
[clippy_lints/src/eq_op.rs:59] right = expr(HirId { owner: DefIndex(24), local_id: 5 }: 1)
[clippy_lints/src/consts.rs:342] self.param_env = ParamEnv {
    caller_bounds: [
        Binder(
            TraitPredicate(<B as std::marker::Sized>),
        ),
        Binder(
            TraitPredicate(<A as std::marker::Sized>),
        ),
    ],
    reveal: UserFacing,
    def_id: None,
}
[clippy_lints/src/consts.rs:343] substs = [
    A,
    B,
]

Perhaps we should just skip generics in eq_op?

Perhaps we should just skip generics in eq_op?

tcx.const_eval should be returning TooGeneric if it can't solve it. I'll investigate why it doesn't.

One thing that I see that's odd is

https://github.com/rust-lang/rust-clippy/blob/2cc23a5b18de3726de81202802fc459559342215/clippy_lints/src/consts.rs#L331

This will always be true.

I've found the problem, it is in rustc. Currently trying to create a rustc-only ICE

Can anyone confirm that the bug is no longer present? (clippy 0.0.212 (e3cb40e 2019-06-25))

https://github.com/rust-lang/rust-clippy/issues/4121#issuecomment-494117277 doesn't crash with nightly-2019-07-01.

I checked both the reduced code and the sized-chunks crate and neither crashed clippy.

I'll add a test in a minute 馃憤

Uh... how was this fixed without https://github.com/rust-lang/rust/pull/63497 ? Did we accidentally add a workaround in clippy?

Was this page helpful?
0 / 5 - 0 ratings