Reproducer:
// compile-flags: -Z unleash-the-miri-inside-of-you
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
use std::panic::Location;
use std::intrinsics::caller_location;
type L = &'static Location<'static>;
#[track_caller]
const fn foo() -> L {
caller_location()
}
const fn bar() -> L {
// Why we need `-Z unleash...`:
let x: fn() -> L = foo;
x()
}
const CTFE: L = bar();
fn main() {
dbg!(bar());
dbg!(CTFE); // This is what causes the ICE.
}
reduced:
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
use std::panic::Location;
use std::intrinsics::caller_location;
type L = &'static Location<'static>;
#[track_caller]
const fn foo() -> L {
caller_location()
}
const fn bar() -> L {
let x: fn() -> L = foo;
x()
}
const CTFE: L = bar();
fn main() {
CTFE;
}
with backtrace:
thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/48840618382eccb8a799320c8e5d08e3b52f4c42/src/libcore/slice/mod.rs:2791:10
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:77
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:1057
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:476
12: rust_begin_unwind
at src/libstd/panicking.rs:380
13: core::panicking::panic_fmt
at src/libcore/panicking.rs:85
14: core::panicking::panic_bounds_check
at src/libcore/panicking.rs:63
15: rustc_mir::interpret::eval_context::InterpCx<M>::layout_of_local
16: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::access_local 17: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_place_to_op
18: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_operand 19: <core::iter::adapters::ResultShunt<I,E> as core::iter::traits::iterator::Iterator>::next
20: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
21: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::step
22: rustc_mir::const_eval::eval_queries::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::machine::<impl rustc_mir::interpret::eval_context::InterpCx<rustc_mir::const_eval::machine::CompileTimeInterpreter>>::try_eval_const_fn_call
28: <rustc_mir::const_eval::machine::CompileTimeInterpreter as rustc_mir::interpret::machine::Machine>::find_mir_or_eval_fn
29: rustc_mir::interpret::terminator::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_fn_call
30: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::step
31: rustc_mir::const_eval::eval_queries::const_eval_raw_provider
32: rustc::ty::query::__query_compute::const_eval_raw
33: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_raw>::compute
34: rustc::dep_graph::graph::DepGraph::with_task_impl
35: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
36: rustc_mir::const_eval::eval_queries::const_eval_validated_provider
37: rustc::ty::query::__query_compute::const_eval_validated
38: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_validated>::compute
39: rustc::dep_graph::graph::DepGraph::with_task_impl
40: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
41: rustc_mir::const_eval::eval_queries::const_eval_validated_provider
42: rustc::ty::query::__query_compute::const_eval_validated
43: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_validated>::compute
44: rustc::dep_graph::graph::DepGraph::with_task_impl
45: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
46: rustc::mir::interpret::queries::<impl rustc::ty::context::TyCtxt>::const_eval_poly
47: <rustc_lint::builtin::UnusedBrokenConst as rustc_lint::passes::LateLintPass>::check_item
48: <rustc_lint::BuiltinCombinedLateLintPass as rustc_lint::passes::LateLintPass>::check_item
49: rustc_hir::intravisit::Visitor::visit_nested_item
50: rustc_hir::intravisit::walk_crate
51: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
52: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
53: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
54: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
55: rustc_session::utils::<impl rustc_session::session::Session>::time
56: rustc_interface::passes::analysis
57: rustc::ty::query::__query_compute::analysis
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::interface::run_compiler_in_existing_thread_pool
62: scoped_tls::ScopedKey<T>::set
63: syntax::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.42.0-nightly (488406183 2020-01-16) running on x86_64-unknown-linux-gnu
note: compiler flags: -Z unleash-the-miri-inside-of-you
query stack during panic:
#0 [const_eval_raw] const-evaluating `bar`
#1 [const_eval_raw] const-evaluating `CTFE`
#2 [const_eval_validated] const-evaluating + checking `CTFE`
#3 [const_eval_validated] const-evaluating + checking `CTFE`
#4 [analysis] running analysis passes on this crate
end of query stack
cc @anp @RalfJung @oli-obk
Also, from the provided description in the reference PR:
In a const context, the attribute does not affect function ABI and instead informs the const
evaluator to continue walking up the stack when probing for the topmost caller location.
...it sounds like this is violating the runtime-compiletime-same-behavior rule. In particular, it sounds like dbg!(bar());
and dbg!(CTFE);
would print out different things. We would get that on stable if we allowed const fn()
pointers.
Relatedly, the following:
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
use std::panic::Location;
use std::intrinsics::caller_location;
type L = &'static Location<'static>;
#[track_caller]
const fn foo() -> L {
caller_location()
}
const fn bar() -> L {
let x: fn() -> L = foo;
x()
}
fn main() {
bar();
}
...results in:
$ RUST_BACKTRACE=1 rustc -Z unleash-the-miri-inside-of-you foo.rs
warning: skipping const checks
--> foo.rs:15:5
|
15 | x()
| ^^^
thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/48840618382eccb8a799320c8e5d08e3b52f4c42/src/libcore/slice/mod.rs:2791:10
stack backtrace:
Incorrect number of arguments passed to called function!
%1 = call align 8 dereferenceable(24) %"core::panic::Location"* @_ZN3foo3foo17h9a95a22c2f60a5e2E()
in function _ZN3foo3bar17hcb643110f71c9dddE
LLVM ERROR: Broken function found, compilation aborted!
...it sounds like this is violating the runtime-compiletime-same-behavior rule
It shouldn't, reification results in a shim which should cause miri to stop walking up the stack, as it looks like a non-#[track_caller]
function calling the #[track_caller]
function.
A real backtrace is needed (we should really try to get nightly to be built with debuginfo-level=1
somehow), but I suspect it's a minor bug similar to the one we fixed in ReifyShim
creation.
Is this reproducible in Miri? I added some tests there for track_caller
and function pointers (https://github.com/rust-lang/miri/pull/1162), and everything looked fine to me.
Incorrect number of arguments passed to called function!
%1 = call align 8 dereferenceable(24) %"core::panic::Location"* @_ZN3foo3foo17h9a95a22c2f60a5e2E()
My first guess here would be that const-prop went wrong, Cc @wesleywiser
@Centril Do I need to pass any flags other than -Z unleash-the-miri-inside-of-you
? I can't get a repro with your test case.
attempt to repro
wesley@endurance:~/code/rust/rust2> cat test.rs
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
use std::panic::Location;
use std::intrinsics::caller_location;
type L = &'static Location<'static>;
#[track_caller]
const fn foo() -> L {
caller_location()
}
const fn bar() -> L {
let x: fn() -> L = foo;
x()
}
const CTFE: L = bar();
fn main() {
CTFE;
}
wesley@endurance:~/code/rust/rust2> rustc +stage1-2 -Z unleash-the-miri-inside-of-you test.rs
warning: skipping const checks
--> test.rs:15:5
|
15 | x()
| ^^^
warning: path statement with no effect
--> test.rs:21:5
|
21 | CTFE;
| ^^^^^
|
= note: `#[warn(path_statements)]` on by default
wesley@endurance:~/code/rust/rust2> git log -1
commit 0d34a8772251b3f9d4dd05c81d9531d455a14fc2 (HEAD, origin/master)
Merge: a2e80300cd8 a606ffdb174
Author: bors <[email protected]>
Date: Mon Feb 3 06:38:34 2020 +0000
Auto merge of #68772 - matthewjasper:relate-opt, r=davidtwco
Avoid exponential behaviour when relating types
When equating bound types we check subtyping in both directions. Since closures are invariant in their substs, we end up comparing the two types an exponential number of times. If there are no bound variables this isn't needed.
Closes #68061
@Centril hang on, isn't this a duplicate of #68178, which https://github.com/rust-lang/rust/pull/68302/commits/19d8527890b59ed25432fbf5a9f1bd75ac814ae2 fixed?
Sadly there's no example of the index out of bounds ICE there, but IIRC @anp hit it for zero-argument functions (like you have here).
@wesleywiser No, just using that flag (on latest master, freshly rebased):
centril@centrilnas2:~/programming/rust/rust-gamma$ git log -1
commit c58e09f138075ce6b3079f41f9c2f192a15b896c (HEAD -> master, upstream/master)
Merge: 0d34a877225 ee601584403
Author: bors <[email protected]>
Date: Mon Feb 3 09:54:09 2020 +0000
Auto merge of #68778 - RalfJung:raw-addr-of, r=eddyb
add raw-addr-of variant to mir_raw_fat_ptr
As suggested at https://github.com/rust-lang/rust/pull/48300#discussion_r372520388
r? @eddyb
centril@centrilnas2:~/programming/rust/rust-gamma$ cat crash.rs
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
use std::panic::Location;
use std::intrinsics::caller_location;
type L = &'static Location<'static>;
#[track_caller]
const fn foo() -> L {
caller_location()
}
const fn bar() -> L {
let x: fn() -> L = foo;
x()
}
fn main() {
bar();
}
centril@centrilnas2:~/programming/rust/rust-gamma$ rustc -Z unleash-the-miri-inside-of-you crash.rs
warning: skipping const checks
--> crash.rs:15:5
|
15 | x()
| ^^^
Incorrect number of arguments passed to called function!
%1 = call align 8 dereferenceable(24) %"core::panic::Location"* @_ZN5crash3foo17he37aca50257bbb93E()
in function _ZN5crash3bar17hc3bef3cb9fdd7a54E
LLVM ERROR: Broken function found, compilation aborted!
thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/48840618382eccb8a799320c8e5d08e3b52f4c42/src/libcore/slice/mod.rs:2791:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
centril@centrilnas2:~/programming/rust/rust-gamma$ cat ref_const.rs
#![feature(core_intrinsics, const_caller_location, track_caller, const_fn)]
use std::panic::Location;
use std::intrinsics::caller_location;
type L = &'static Location<'static>;
#[track_caller]
const fn foo() -> L {
caller_location()
}
const fn bar() -> L {
let x: fn() -> L = foo;
x()
}
const CTFE: L = bar();
fn main() {
CTFE;
}
centril@centrilnas2:~/programming/rust/rust-gamma$ RUST_BACKTRACE=1 rustc -Z unleash-the-miri-inside-of-you ref_const.rs
warning: skipping const checks
--> ref_const.rs:15:5
|
15 | x()
| ^^^
thread 'rustc' panicked at 'index out of bounds: the len is 1 but the index is 1', /rustc/48840618382eccb8a799320c8e5d08e3b52f4c42/src/libcore/slice/mod.rs:2791:10
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.40/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:77
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:1057
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:476
12: rust_begin_unwind
at src/libstd/panicking.rs:380
13: core::panicking::panic_fmt
at src/libcore/panicking.rs:85
14: core::panicking::panic_bounds_check
at src/libcore/panicking.rs:63
15: rustc_mir::interpret::eval_context::InterpCx<M>::layout_of_local
16: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::access_local
17: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_place_to_op
18: rustc_mir::interpret::operand::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_operand
19: <core::iter::adapters::ResultShunt<I,E> as core::iter::traits::iterator::Iterator>::next
20: <alloc::vec::Vec<T> as alloc::vec::SpecExtend<T,I>>::from_iter
21: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::step
22: rustc_mir::const_eval::eval_queries::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::machine::<impl rustc_mir::interpret::eval_context::InterpCx<rustc_mir::const_eval::machine::CompileTimeInterpreter>>::try_eval_const_fn_call
28: <rustc_mir::const_eval::machine::CompileTimeInterpreter as rustc_mir::interpret::machine::Machine>::find_mir_or_eval_fn
29: rustc_mir::interpret::terminator::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::eval_fn_call
30: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpCx<M>>::step
31: rustc_mir::const_eval::eval_queries::const_eval_raw_provider
32: rustc::ty::query::__query_compute::const_eval_raw
33: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_raw>::compute
34: rustc::dep_graph::graph::DepGraph::with_task_impl
35: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
36: rustc_mir::const_eval::eval_queries::const_eval_validated_provider
37: rustc::ty::query::__query_compute::const_eval_validated
38: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_validated>::compute
39: rustc::dep_graph::graph::DepGraph::with_task_impl
40: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
41: rustc_mir::const_eval::eval_queries::const_eval_validated_provider
42: rustc::ty::query::__query_compute::const_eval_validated
43: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors for rustc::ty::query::queries::const_eval_validated>::compute
44: rustc::dep_graph::graph::DepGraph::with_task_impl
45: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt>::get_query
46: rustc::mir::interpret::queries::<impl rustc::ty::context::TyCtxt>::const_eval_poly
47: <rustc_lint::builtin::UnusedBrokenConst as rustc_lint::passes::LateLintPass>::check_item
48: <rustc_lint::BuiltinCombinedLateLintPass as rustc_lint::passes::LateLintPass>::check_item
49: rustc_hir::intravisit::Visitor::visit_nested_item
50: rustc_hir::intravisit::walk_crate
51: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
52: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
53: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
54: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
55: rustc_session::utils::<impl rustc_session::session::Session>::time
56: rustc_interface::passes::analysis
57: rustc::ty::query::__query_compute::analysis
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::interface::run_compiler_in_existing_thread_pool
62: scoped_tls::ScopedKey<T>::set
63: syntax::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.42.0-nightly (488406183 2020-01-16) running on x86_64-unknown-linux-gnu
note: compiler flags: -Z unleash-the-miri-inside-of-you
query stack during panic:
#0 [const_eval_raw] const-evaluating `bar`
#1 [const_eval_raw] const-evaluating `CTFE`
#2 [const_eval_validated] const-evaluating + checking `CTFE`
#3 [const_eval_validated] const-evaluating + checking `CTFE`
#4 [analysis] running analysis passes on this crate
end of query stack
@Centril would you happen to have LLVM assertions enabled, which @wesleywiser might not?
The following is the only modifications made to config.toml
:
# Whether or not debug assertions are enabled for the compiler and standard
# library.
debug-assertions = true
# Debuginfo level for most of Rust code, corresponds to the `-C debuginfo=N` option of `rustc`.
# `0` - no debug info
# `1` - line tables only
# `2` - full debug info with variable and type information
# Can be overriden for specific subsets of Rust code (rustc, std or tools).
# Debuginfo for tests run with compiletest is not controlled by this option
# and needs to be enabled separately with `debuginfo-level-tests`.
#debuginfo-level = if debug { 2 } else { 0 }
debuginfo-level = 2
where gamma-stage1
was built with clear && ./x.py test --stage 1 --bless --pass check src/test/ui/
.
Per @eddyb's advice, I'll try to nuke build/*/stage1-std
to see if it reproduces.
note: rustc 1.42.0-nightly (488406183 2020-01-16) running on x86_64-unknown-linux-gnu
The ICE message betrays the old nightly you're still using, heh.
Yeah oops; I was forgetting to add +gamma-stage1
to rustc
... damn, still tired from tomorrow I guess, sorry for the noise!
still tired from tomorrow
I won't tell anyone about your secret if you also let me use that time machine. :D
Most helpful comment
I won't tell anyone about your secret if you also let me use that time machine. :D