rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
99.14k stars 12.8k forks source link

Internal compiler error caused by generics and closure to fn pointer coercion #42718

Closed kriomant closed 7 years ago

kriomant commented 7 years ago

Following code causes internal compiler error on nighly:

pub struct A<T> {
    _item: T,
}
impl<T> A<T> {
    fn foo(&self) {
        let _: fn() = || {};
    }
}

fn main() {
    let a = A::<i32> { _item: 0 };
    a.foo();
}

Error:

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.19.0-nightly (fe7227f6c 2017-06-16) running on x86_64-apple-darwin

note: run with `RUST_BACKTRACE=1` for a backtrace

thread 'rustc' panicked at 'substs of instance DefId { krate: CrateNum(0), node: DefIndex(2147483661) => associated_types/32d60c5::{{impl}}[0]::create[0]::{{closure}}[0] } not normalized for trans: Slice([T])', src/librustc/ty/instance.rs:112
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
stack backtrace:
   0: std::sys::imp::backtrace::tracing::imp::unwind_backtrace
   1: std::panicking::default_hook::{{closure}}
   2: std::panicking::default_hook
   3: std::panicking::rust_panic_with_hook
   4: std::panicking::begin_panic
   5: std::panicking::begin_panic_fmt
   6: rustc::ty::instance::Instance::new
   7: rustc_trans::monomorphize::resolve_closure
   8: rustc_trans::monomorphize::resolve
   9: <rustc_trans::collector::MirNeighborCollector<'a, 'tcx> as rustc::mir::visit::Visitor<'tcx>>::visit_terminator_kind
  10: rustc::mir::visit::Visitor::visit_mir
  11: rustc_trans::collector::collect_items_rec
  12: rustc_trans::collector::collect_items_rec
  13: rustc_trans::collector::collect_items_rec
  14: rustc_trans::base::collect_and_partition_translation_items::{{closure}}
  15: rustc_trans::base::trans_crate
  16: rustc_driver::driver::phase_4_translate_to_llvm
  17: rustc_driver::driver::compile_input::{{closure}}
  18: rustc_driver::driver::phase_3_run_analysis_passes::{{closure}}
  19: rustc_driver::driver::phase_3_run_analysis_passes
  20: rustc_driver::driver::compile_input
  21: rustc_driver::run_compiler
est31 commented 7 years ago

Also occurs on beta.

Mark-Simulacrum commented 7 years ago

The regression here is only that this doesn't ICE on stable, presumably because the relevant code isn't reached. Still a regression once it goes through the trains, though.

est31 commented 7 years ago

@Mark-Simulacrum yeah its an ICE related to the freshly stabilized closure to fn coercion feature.

est31 commented 7 years ago

Smaller reproducing example:

fn foo<T>(_: T) {
    let _: fn() = || {};
}

fn main() {
    foo(0i8);
}
est31 commented 7 years ago

Hmm apparently the TypeFlags::HAS_PARAMS flag is still set (all other flags are not). No idea what that means though. Similar issue #36381 got fixed by making the check less strict.

eddyb commented 7 years ago

@est31 Well that's a consequence of there being type parameters. And it's in the ICE message. So the immediate conclusion is that parameters were not substituted correctly at some point.

Specifically, this operation is missing for source_ty below it, for ClosureFnPointer.