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: const eval error with an empty slice. #64945

Closed
rodrimati1992 opened this issue Oct 1, 2019 · 3 comments · Fixed by #64967
Closed

ICE: const eval error with an empty slice. #64945

rodrimati1992 opened this issue Oct 1, 2019 · 3 comments · Fixed by #64967
Labels
A-const-eval Area: constant evaluation (mir interpretation) A-typesystem Area: The type system C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@rodrimati1992
Copy link
Contributor

This code:

pub struct Slice<'a, T>(&'a [T]);

impl<'a, T: 'a> Slice<'a, T> {
    pub const EMPTY: Self = Slice ({
        let v: &[T] = &[];
        v
    });
}

Errors on rustc 1.40.0-nightly (22bc9e1d9 2019-09-30) running on x86_64-unknown-linux-gnu with this message:

   Compiling playground v0.0.1 (/playground)
[ERROR rustc_mir::transform::qualify_consts] old validator: []
[ERROR rustc_mir::transform::qualify_consts] new validator: [(src/lib.rs:5:24: 5:26, "LiveDrop")]
error: internal compiler error: src/librustc_mir/transform/qualify_consts.rs:1038: Disagreement between legacy and dataflow-based const validators.
    After filing an issue, use `-Zsuppress-const-validation-back-compat-ice` to compile your code.
 --> src/lib.rs:4:5
  |
4 | /     pub const EMPTY: Self = Slice ({
5 | |         let v: &[T] = &[];
6 | |         v
7 | |     });
  | |_______^

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:871:9
stack backtrace:
   0: backtrace::backtrace::libunwind::trace
             at /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/libunwind.rs:88
   1: backtrace::backtrace::trace_unsynchronized
             at /cargo/registry/src/git.luolix.top-1ecc6299db9ec823/backtrace-0.3.37/src/backtrace/mod.rs:66
   2: std::sys_common::backtrace::_print_fmt
             at src/libstd/sys_common/backtrace.rs:76
   3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
             at src/libstd/sys_common/backtrace.rs:60
   4: core::fmt::write
             at src/libcore/fmt/mod.rs:1028
   5: std::io::Write::write_fmt
             at src/libstd/io/mod.rs:1412
   6: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:64
   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:196
   9: std::panicking::default_hook
             at src/libstd/panicking.rs:210
  10: rustc_driver::report_ice
  11: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:477
  12: std::panicking::begin_panic
  13: rustc_errors::HandlerInner::span_bug
  14: rustc_errors::Handler::span_bug
  15: rustc::util::bug::opt_span_bug_fmt::{{closure}}
  16: rustc::ty::context::tls::with_opt::{{closure}}
  17: rustc::ty::context::tls::with_context_opt
  18: rustc::ty::context::tls::with_opt
  19: rustc::util::bug::opt_span_bug_fmt
  20: rustc::util::bug::span_bug_fmt
  21: rustc_mir::transform::qualify_consts::Checker::check_const
  22: rustc_mir::transform::qualify_consts::mir_const_qualif
  23: rustc::ty::query::__query_compute::mir_const_qualif
  24: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_const_qualif>::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::transform::mir_validated
  28: rustc::ty::query::__query_compute::mir_validated
  29: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_validated>::compute
  30: rustc::dep_graph::graph::DepGraph::with_task_impl
  31: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  32: rustc_mir::borrow_check::mir_borrowck
  33: rustc::ty::query::__query_compute::mir_borrowck
  34: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::mir_borrowck>::compute
  35: rustc::dep_graph::graph::DepGraph::with_task_impl
  36: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  37: rustc::ty::<impl rustc::ty::context::TyCtxt>::par_body_owners
  38: rustc::util::common::time
  39: rustc_interface::passes::analysis
  40: rustc::ty::query::__query_compute::analysis
  41: rustc::dep_graph::graph::DepGraph::with_task_impl
  42: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
  43: rustc_interface::passes::BoxedGlobalCtxt::access::{{closure}}
  44: rustc_interface::passes::create_global_ctxt::{{closure}}
  45: rustc_interface::interface::run_compiler_in_existing_thread_pool
  46: std::thread::local::LocalKey<T>::with
  47: scoped_tls::ScopedKey<T>::set
  48: syntax::with_globals
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/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.40.0-nightly (22bc9e1d9 2019-09-30) running on x86_64-unknown-linux-gnu

note: compiler flags: -C codegen-units=1 -C debuginfo=2 --crate-type lib

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

query stack during panic:
#0 [mir_const_qualif] processing `Slice::<'a, T>::EMPTY`
#1 [mir_validated] processing `Slice::<'a, T>::EMPTY`
#2 [mir_borrowck] processing `Slice::<'a, T>::EMPTY`
#3 [analysis] running analysis passes on this crate
end of query stack
error: aborting due to previous error

error: could not compile `playground`.

To learn more, run the command again with --verbose.
@rodrimati1992 rodrimati1992 changed the title ICE: new const eval error with an empty slice. ICE: const eval error with an empty slice. Oct 1, 2019
@Centril Centril added A-const-eval Area: constant evaluation (mir interpretation) A-typesystem Area: The type system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ I-nominated T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 1, 2019
@Centril
Copy link
Contributor

Centril commented Oct 1, 2019

cc @ecstatic-morse @oli-obk

@jonas-schievink jonas-schievink added the C-bug Category: This is a bug. label Oct 1, 2019
@hellow554
Copy link
Contributor

regression in 0bbab7d

@Centril Centril added regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. P-high High priority labels Oct 1, 2019
@ecstatic-morse
Copy link
Contributor

ecstatic-morse commented Oct 1, 2019

I'm still building a compiler with graphviz debugging enabled so I can have a closer look, but I have a theory.

I believe the problem is that we are too conservative when marking locals as indirectly mutable. Because we pessimistically assume that type T is !Freeze, we also assume that type [T; 0] can be mutated through a shared reference. Once a shared reference to it is taken, we assume that all qualifs that could apply to [T; 0] are applied to that local. We should special case zero-sized arrays here, so when the borrow of [T; 0] occurs, it is not marked as indirectly mutable. Perhaps we could assume that zero-sized arrays never actually Drop as well?

While this change would solve this particular issue, I believe that this won't solve the problem entirely. What if we take two references to the zero-sized type (&&[])? While the local containing the ZST itself will not be marked as indirectly mutable, the local containing the first borrow will be, which diverges from the old analysis. We may need to base whether a Local is indirectly mutable on the HasMutInterior analysis.

ecstatic-morse added a commit to ecstatic-morse/rust that referenced this issue Oct 1, 2019
This also tests that `&&[]` no longer causes an ICE in this PR (although
the test fails the borrow checker). This could be more complete.
Centril added a commit to Centril/rust that referenced this issue Oct 1, 2019
Don't mark borrows of zero-sized arrays as indirectly mutable

Resolves rust-lang#64945

r? @oli-obk
ecstatic-morse added a commit to ecstatic-morse/rust that referenced this issue Oct 1, 2019
This also tests that `&&[]` no longer causes an ICE in this PR (although
the test fails the borrow checker). This could be more complete.
@bors bors closed this as completed in ccf1d9c Oct 2, 2019
bors added a commit that referenced this issue Oct 14, 2019
Return `false` from `needs_drop` for all zero-sized arrays.

Resolves #65348.

This changes the result of the `needs_drop` query from `true` to `false` for types such as `[Box<i32>; 0]`. I believe this change to be sound because a zero-sized array can never actually hold a value. This is an elegant way of resolving #65348 and #64945, but obviously it has much broader implications.
Centril added a commit to Centril/rust that referenced this issue Oct 15, 2019
…drop, r=eddyb

Return `false` from `needs_drop` for all zero-sized arrays.

Resolves rust-lang#65348.

This changes the result of the `needs_drop` query from `true` to `false` for types such as `[Box<i32>; 0]`. I believe this change to be sound because a zero-sized array can never actually hold a value. This is an elegant way of resolving rust-lang#65348 and rust-lang#64945, but obviously it has much broader implications.
Centril added a commit to Centril/rust that referenced this issue Oct 15, 2019
…drop, r=eddyb

Return `false` from `needs_drop` for all zero-sized arrays.

Resolves rust-lang#65348.

This changes the result of the `needs_drop` query from `true` to `false` for types such as `[Box<i32>; 0]`. I believe this change to be sound because a zero-sized array can never actually hold a value. This is an elegant way of resolving rust-lang#65348 and rust-lang#64945, but obviously it has much broader implications.
tmandry added a commit to tmandry/rust that referenced this issue Oct 15, 2019
…drop, r=eddyb

Return `false` from `needs_drop` for all zero-sized arrays.

Resolves rust-lang#65348.

This changes the result of the `needs_drop` query from `true` to `false` for types such as `[Box<i32>; 0]`. I believe this change to be sound because a zero-sized array can never actually hold a value. This is an elegant way of resolving rust-lang#65348 and rust-lang#64945, but obviously it has much broader implications.
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 (mir interpretation) A-typesystem Area: The type system C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ P-high High priority regression-from-stable-to-nightly Performance or correctness regression from stable to nightly. 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.

5 participants