Skip to content

ICE whilst experimenting with opaque/existential types. #70877

Closed
@mental32

Description

@mental32
Contributor

ICE whilst experimenting with opaque/existential types.

I tried this code:

#![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_bindings)]

type FooArg<'a> = &'a dyn ToString;
type FooRet = impl std::fmt::Debug;

type FooItem = Box<dyn Fn(FooArg) -> FooRet>;
type Foo = impl Iterator<Item = FooItem>;

#[repr(C)]
struct Bar(u8);

impl Iterator for Bar {
    type Item = FooItem;

    fn next(&mut self) -> Option<Self::Item> {
        Some(Box::new(quux))
    }
}

fn quux(st: FooArg) -> FooRet {
    Some(st.to_string())
}

fn ham() -> Foo {
    Bar(1)
}

fn oof() -> impl std::fmt::Debug {
    let mut bar = ham();
    let func = bar.next().unwrap();
    return func(&"oof");
}

fn main() {
    println!("{:?}", oof());
}

I expected to see this happen: "oof" in stdout

Instead, this happened: ICE!

warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
 --> oops.rs:2:12
  |
2 | #![feature(impl_trait_in_bindings)]
  |            ^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default

error: internal compiler error: Non-defining use of DefId(0:5 ~ oops[317d]::FooRet[0]) with revealed type
  --> oops.rs:25:1
   |
25 | / fn ham() -> Foo {
26 | |     Bar(1)
27 | | }
   | |_^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:355:17
note: run with `RUST_BACKTRACE=1` environment variable to display a 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.43.0-nightly (564758c4c 2020-03-08) running on x86_64-unknown-linux-gnu

Meta

rustc --version --verbose:

rustc 1.43.0-nightly (564758c4c 2020-03-08)
binary: rustc
commit-hash: 564758c4c329e89722454dd2fbb35f1ac0b8b47c
commit-date: 2020-03-08
host: x86_64-unknown-linux-gnu
release: 1.43.0-nightly
LLVM version: 9.0

Backtrace:

(The above backtrace but with RUST_BACKTRACE="full")

RUST_BACKTRACE="full" rustc oops.rs                                                                                                                                                                                                                                                                      08:58:45
warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash
 --> oops.rs:2:12
  |
2 | #![feature(impl_trait_in_bindings)]
  |            ^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(incomplete_features)]` on by default

error: internal compiler error: Non-defining use of DefId(0:5 ~ oops[317d]::FooRet[0]) with revealed type
  --> oops.rs:25:1
   |
25 | / fn ham() -> Foo {
26 | |     Bar(1)
27 | | }
   | |_^

thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:355:17
stack backtrace:
   0:     0x7f1023ca0784 - backtrace::backtrace::libunwind::trace::h6c956c3ba1fc7bb8
                               at /cargo/registry/src/github.tiyicn.workers.dev-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/libunwind.rs:86
   1:     0x7f1023ca0784 - backtrace::backtrace::trace_unsynchronized::ha74600fd7051fbcc
                               at /cargo/registry/src/github.tiyicn.workers.dev-1ecc6299db9ec823/backtrace-0.3.44/src/backtrace/mod.rs:66
   2:     0x7f1023ca0784 - std::sys_common::backtrace::_print_fmt::h136191e12f9131d1
                               at src/libstd/sys_common/backtrace.rs:78
   3:     0x7f1023ca0784 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::he1b6d1e88d44f14b
                               at src/libstd/sys_common/backtrace.rs:59
   4:     0x7f1023cda05c - core::fmt::write::h2da0f6fb1c5744aa
                               at src/libcore/fmt/mod.rs:1063
   5:     0x7f1023c92397 - std::io::Write::write_fmt::h565a38f626356c9a
                               at src/libstd/io/mod.rs:1428
   6:     0x7f1023ca5495 - std::sys_common::backtrace::_print::hb8c44fcba2bbae0d
                               at src/libstd/sys_common/backtrace.rs:62
   7:     0x7f1023ca5495 - std::sys_common::backtrace::print::h450b65b78884d83c
                               at src/libstd/sys_common/backtrace.rs:49
   8:     0x7f1023ca5495 - std::panicking::default_hook::{{closure}}::hf2107f0d1e85e58b
                               at src/libstd/panicking.rs:204
   9:     0x7f1023ca51e2 - std::panicking::default_hook::hed6039e35bf0a02a
                               at src/libstd/panicking.rs:224
  10:     0x7f10242f3899 - rustc_driver::report_ice::h79c3287ca6d2e7bd
  11:     0x7f1023ca5bc5 - std::panicking::rust_panic_with_hook::hfa422439ae633a29
                               at src/libstd/panicking.rs:474
  12:     0x7f1026a6f8ce - std::panicking::begin_panic::h4ebe9e0d0c9344b8
  13:     0x7f1026aa5f2f - <rustc_errors::HandlerInner as core::ops::drop::Drop>::drop::h9b8649ccf972c411
  14:     0x7f102430dc36 - core::ptr::drop_in_place::ha73c7e95b0d52445
  15:     0x7f102431256d - <alloc::rc::Rc<T> as core::ops::drop::Drop>::drop::hb9da4511e93091f7
  16:     0x7f10243606fd - core::ptr::drop_in_place::hdcab46d2516c088e
  17:     0x7f10243478f2 - rustc_interface::interface::run_compiler_in_existing_thread_pool::h6fcbd3ddf26127ee
  18:     0x7f10242fb34c - std::sys_common::backtrace::__rust_begin_short_backtrace::hbc599e437c563f62
  19:     0x7f1023cb7dd7 - __rust_maybe_catch_panic
                               at src/libpanic_unwind/lib.rs:86
  20:     0x7f102434a056 - core::ops::function::FnOnce::call_once{{vtable.shim}}::h29932a57129906c8
  21:     0x7f1023c8211f - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h17bc559ade1f3898
                               at /rustc/564758c4c329e89722454dd2fbb35f1ac0b8b47c/src/liballoc/boxed.rs:1017
  22:     0x7f1023cb66e0 - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h5f4de8825e11517b
                               at /rustc/564758c4c329e89722454dd2fbb35f1ac0b8b47c/src/liballoc/boxed.rs:1017
  23:     0x7f1023cb66e0 - std::sys_common::thread::start_thread::h9d05d51d7326efdc
                               at src/libstd/sys_common/thread.rs:13
  24:     0x7f1023cb66e0 - std::sys::unix::thread::Thread::new::thread_start::hc91805f14c4a4cf3
                               at src/libstd/sys/unix/thread.rs:80
  25:     0x7f1023bc346f - start_thread
  26:     0x7f1023ae33d3 - clone
  27:                0x0 - <unknown>

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.43.0-nightly (564758c4c 2020-03-08) running on x86_64-unknown-linux-gnu

query stack during panic:
end of query stack

Activity

changed the title [-]ICE whilst experimenting with opaque types.[/-] [+]ICE whilst experimenting with opaque/existential types.[/+] on Apr 7, 2020
mental32

mental32 commented on Apr 7, 2020

@mental32
ContributorAuthor

I can still reproduce the issue after a rustup update, new output of rustc --version --verbose:

rustc 1.44.0-nightly (6dee5f112 2020-04-06)
binary: rustc
commit-hash: 6dee5f1126dfd5c9314ee5ae9d9eb010e35ef257
commit-date: 2020-04-06
host: x86_64-unknown-linux-gnu
release: 1.44.0-nightly
LLVM version: 9.0
added
A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.
C-bugCategory: This is a bug.
I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
requires-nightlyThis issue requires a nightly compiler in some way.
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Apr 7, 2020
davidtwco

davidtwco commented on Jun 11, 2020

@davidtwco
Member

Not completely sure, but I think this might be another example of this ICE (playground):

#![feature(type_alias_impl_trait)]

pub trait Baz { }

impl Baz for () { }

type Qux = impl Baz;

pub trait Foo {
    type Assoc;
}

impl Foo for () {
    type Assoc = Qux;
}

type Bar = impl Foo<Assoc = Qux>;

fn assign() -> Bar {}

fn assign2() -> Qux {}

extern "C" {
    pub fn lint_me() -> <Bar as Foo>::Assoc;
}

fn main() {}
davidtwco

davidtwco commented on Jun 14, 2020

@davidtwco
Member

I've looked into this a little bit - I don't know what the correct behavior is, but hopefully this saves someone some time when they go to fix this (or someone can tell me what the correct behavior is and I can fix it). The following assumes the test case from my previous comment.

This error is emitted during MIR type-check here:

tcx.sess.delay_span_bug(
body.span,
&format!(
"Non-defining use of {:?} with revealed type",
opaque_def_id,
),
);

It happens when the DefId isn't in concrete_opaque_types in TypeckTables. concrete_opaque_types is added to during typeck writeback, here:

let old = self.tables.concrete_opaque_types.insert(def_id, new);

In particular, this case is when we're considering the TypeckTables for assign, where fcx.opaque_types has two values - Bar and Qux. For Qux, we end up infering the concrete type to be Qux and fall into this branch:

if def_id == defin_ty_def_id {
debug!(
"skipping adding concrete definition for opaque type {:?} {:?}",
opaque_defn, defin_ty_def_id
);
skip_add = true;
}

This code exists to avoid considering foo1 a defining use in this example:

#![feature(type_alias_impl_trait)]
trait TA {}
impl TA for () {} 
type A = impl TA;
fn foo() -> A { } // defining use
fn foo1() -> A { foo() } // not a defining use

fcx.opaque_types gets those values here from opaque_type_map, which is returned from instantiate_opaque_types:

for (ty, decl) in opaque_type_map {
let _ = opaque_types.insert(ty, decl);
let _ = opaque_types_vars.insert(decl.concrete_ty, decl.opaque_type);
}

That ends up at instantiate_opaque_types_in_map here:

fn instantiate_opaque_types_in_map<T: TypeFoldable<'tcx>>(&mut self, value: &T) -> T {

This looks over the type (in this case, the return type, Bar, of assign, whose definition is impl Foo<Assoc = Qux>) and looks for the opaque types, and creates inference variables for their concrete types.

As a result of this, assign is effectively considered a defining use for both Bar and Qux. Bar is inferred to be () - trivially, because of the return value of assign.

Because Qux is used in the type of Bar, whatever type that ends up being will be considered a defining use of Qux too - and the impl of Foo for () (what Bar is) says that <Bar as Foo>::Assoc should be Qux - so Qux's concrete type is considered to be Qux. That triggers the logic in writeback where we skip adding the concrete type to concrete_opaque_types - and hence the ICE in MIR type check.

As I see it, there are two possible options here:

  1. Don't consider Qux a defining use in this case (when the use in the return type is in a bound), so the concrete type will come from the other defining uses.

  2. Determine that the inference variable that ends up being Qux doesn't come from a defining use (but from the trait implementation) and so should be ignored or an error emitted.

added
E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.
on Oct 7, 2020

7 remaining items

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.E-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.F-impl_trait_in_bindings`#![feature(impl_trait_in_bindings)]`F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.glacierICE tracked in rust-lang/glacier.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @davidtwco@jonas-schievink@JohnTitor@mental32@rust-lang-glacier-bot

      Issue actions

        ICE whilst experimenting with opaque/existential types. · Issue #70877 · rust-lang/rust