Rust: ICE when compiling `const fn` that calls a non-const function through a pointer

Created on 22 Nov 2018  路  6Comments  路  Source: rust-lang/rust

My minimal reproduction:

#![feature(const_fn)]

const fn bad(input: fn()) {
    input()
}

fn main() {
    bad(|| {});
}

Sidenote: I'm pretty sure this is the smallest working ICE that I've seen in Rust so far.

A-const-eval A-const-fn E-easy E-mentor I-ICE

Most helpful comment

I would like to have a go at fixing this later today and tomorrow at RustFest.

All 6 comments

r? @oli-obk

It doesn't require main to panic

#![feature(const_fn)]
const fn bad(input: fn()) {
    input()
}

playground

error: internal compiler error: should have reported an error about non-const fn calls in constants
 --> src/lib.rs:4:5
  |
4 |     input()
  |     ^^^^^^^

thread 'main' panicked at 'no errors encountered even though `delay_span_bug` issued', librustc_errors/lib.rs:334:17

stack backtrace:

   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at libstd/sys/unix/backtrace/tracing/gcc_s.rs:49
   1: std::sys_common::backtrace::_print
             at libstd/sys_common/backtrace.rs:71
   2: std::panicking::default_hook::{{closure}}
             at libstd/sys_common/backtrace.rs:59
             at libstd/panicking.rs:211
   3: std::panicking::default_hook
             at libstd/panicking.rs:227
   4: rustc::util::common::panic_hook
   5: std::panicking::rust_panic_with_hook
             at libstd/panicking.rs:480
   6: std::panicking::begin_panic
   7: <rustc_errors::Handler as core::ops::drop::Drop>::drop
   8: core::ptr::drop_in_place
   9: core::ptr::drop_in_place
  10: core::ptr::drop_in_place
  11: syntax::with_globals
  12: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  13: rustc_driver::run
  14: rustc_driver::main
  15: std::rt::lang_start::{{closure}}
  16: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  17: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:102
  18: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:398
             at libstd/rt.rs:58
  19: main
  20: __libc_start_main
  21: <unknown>
query stack during panic:
end of query stack

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.32.0-nightly (0b9f19dff 2018-11-21) 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

  1. https://github.com/rust-lang/rust/blob/6a2d1b4e15d5de90f8c36181b1d429da658adfd2/src/librustc_mir/transform/qualify_consts.rs#L849 needs to be turned into a match

  2. add an arm for FnPtr and reports an error about calling function pointers being not allowed in const fn

  3. add an _ arm and report span_bug!
  4. Run tests and see where we hit the span_bug! and add arms for the newly found calls
  5. Add test for const fn foo() { (||{})() } (calling a closure in a const fn)

I would like to have a go at fixing this later today and tomorrow at RustFest.

It looks like I got stuck and need some pointers on how to continue.

I changed the if let to a match and added the new match branch:
https://github.com/rust-lang/rust/compare/master...phansch:fix_const_ice?w=1#diff-c2552a106550d05b69d5e07612f0f812R988

However, running this triggers the FnPtr code in existing Rust code here:

error: function pointers are not allowed in const fn                   ] 17/29: core
    --> src/libcore/fmt/mod.rs:1042:17
     |
1042 |                 (arg.formatter)(arg.value, &mut formatter)?;
     |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: function pointers are not allowed in const fn
    --> src/libcore/fmt/mod.rs:1104:9
     |
1104 |         (value.formatter)(value.value, self)
     |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I'm not sure whether the FnPtr branch needs additional conditionals or if this is a legitimate issue?

heh, right, so const_qualif also runs on normal functions to not duplicate code for promotion. You need to wrap the error reporting in another if self.mode != Mode::Fn

Was this page helpful?
0 / 5 - 0 ratings