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 with const transmute and existential type #53087

Closed
DutchGhost opened this Issue Aug 5, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@DutchGhost
Copy link

DutchGhost commented Aug 5, 2018

Not sure if it's really something that is ever gonna happen in real code, but the following ICE's:

#![feature(existential_type)]
#![feature(const_fn)]
#![feature(untagged_unions)]

const fn transmute<T, U>(t: T) -> U {
    union Transform<TT, UU> {
        t: TT,
        u: UU,
    }
    
    unsafe { Transform { t }.u }
}


existential type Foo: Fn();
const foo: Foo = transmute(|| {});

fn bar() -> Foo { || {} }

fn main() {
    foo();
}
Backtrace:
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `Foo`,
 right: `[closure@src/main.rs:18:19: 18:24]`', librustc_mir/transform/const_prop.rs:338: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
             at libstd/sys_common/backtrace.rs:59
   2: std::panicking::default_hook::{{closure}}
             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:479
   6: std::panicking::continue_panic_fmt
             at libstd/panicking.rs:390
   7: std::panicking::begin_panic_fmt
             at libstd/panicking.rs:345
   8: <rustc_mir::transform::const_prop::ConstPropagator<'b, 'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_statement
   9: <rustc_mir::transform::const_prop::ConstProp as rustc_mir::transform::MirPass>::run_pass
  10: rustc_mir::transform::optimized_mir::{{closure}}
  11: rustc_mir::transform::optimized_mir
  12: rustc::ty::query::__query_compute::optimized_mir
  13: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::optimized_mir<'tcx>>::compute
  14: rustc::dep_graph::graph::DepGraph::with_task_impl
  15: rustc::ty::context::tls::with_related_context
  16: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  17: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_get_query
  18: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::instance_mir
  19: rustc_mir::monomorphize::collector::collect_items_rec
  20: rustc_mir::monomorphize::collector::collect_crate_mono_items::{{closure}}
  21: rustc::util::common::time
  22: rustc_mir::monomorphize::collector::collect_crate_mono_items
  23: rustc::util::common::time
  24: rustc_codegen_llvm::base::collect_and_partition_mono_items
  25: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::collect_and_partition_mono_items<'tcx>>::compute
  26: rustc::dep_graph::graph::DepGraph::with_task_impl
  27: rustc::ty::context::tls::with_related_context
  28: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
  29: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
  30: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_utils::codegen_backend::CodegenBackend>::codegen_crate
  31: rustc::util::common::time
  32: rustc_driver::driver::phase_4_codegen
  33: rustc_driver::driver::compile_input::{{closure}}
  34: rustc::ty::context::tls::enter_context
  35: <std::thread::local::LocalKey<T>>::with
  36: rustc::ty::context::TyCtxt::create_and_enter
  37: rustc_driver::driver::compile_input
  38: rustc_driver::run_compiler_with_pool
  39: <scoped_tls::ScopedKey<T>>::set
  40: syntax::with_globals
  41: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  42: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  43: rustc_driver::run
  44: rustc_driver::main
  45: std::rt::lang_start::{{closure}}
  46: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  47: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  48: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:392
             at libstd/rt.rs:58
  49: main
  50: __libc_start_main
  51: <unknown>
query stack during panic:
#0 [optimized_mir] processing `main`
#1 [collect_and_partition_mono_items] collect_and_partition_mono_items
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.30.0-nightly (3edb355b7 2018-08-03) running on x86_64-unknown-linux-gnu

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

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

error: Could not compile `playground`.

To learn more, run the command again with --verbose.
@DutchGhost

This comment has been minimized.

Copy link
Author

DutchGhost commented Aug 5, 2018

Just figured out that declaring the existential type like this:
existential type Foo: Fn() + Copy won't panic. I guess because its being copied?
But I think that it should not be allowed,

#![feature(existential_type)]
#![feature(const_fn)]
#![feature(untagged_unions)]

const fn transmute<T, U>(t: T) -> U {
    union Transform<TT, UU> {
        t: TT,
        u: UU,
    }
    
    unsafe { Transform { t }.u }
}


existential type Foo: Fn() + Copy;
const BAZR: Foo = transmute(|| {});

fn bar() -> Foo { || {} }

fn main() {
    let x = BAZR();
    
    println!("{:?}", x);
}
@DutchGhost

This comment has been minimized.

Copy link
Author

DutchGhost commented Aug 5, 2018

A version without transmutes and unsafe {}, but with pointer casts instead:

#![feature(existential_type)]

existential type Foo: Copy;

const BAZ: *const Foo = &0u8 as *const _ as *const _;

fn bar() -> Foo { 0u32 }

fn main() {
    let _ = BAZ;
}

bors added a commit that referenced this issue Aug 8, 2018

Auto merge of #53163 - oli-obk:const_prop_ice, r=nikomatsakis
Remove an overly pedantic and wrong assertion

fixes #53157
fixes #53087

@bors bors closed this in #53163 Aug 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment