Skip to content

Implementing trait for Existential type ICE's #53345

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

Closed
DutchGhost opened this issue Aug 14, 2018 · 6 comments
Closed

Implementing trait for Existential type ICE's #53345

DutchGhost opened this issue Aug 14, 2018 · 6 comments
Assignees
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@DutchGhost
Copy link
Contributor

DutchGhost commented Aug 14, 2018

Trying to implement a trait for an existential type, ICE's:

#![feature(existential_type)]

existential type Bar: PartialEq;

fn bazr() -> Bar { }

impl Eq for Bar {}

fn main() {}
Backtrace:
 Compiling playground v0.0.1 (file:///playground)
error: internal compiler error: librustc/traits/coherence.rs:487: ty_is_local invoked on unexpected type: Bar

thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:579:9
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::begin_panic
   7: rustc_errors::Handler::bug
   8: rustc::util::bug::opt_span_bug_fmt::{{closure}}
   9: rustc::ty::context::tls::with_opt::{{closure}}
  10: rustc::ty::context::tls::with_context_opt
  11: rustc::ty::context::tls::with_opt
  12: rustc::util::bug::opt_span_bug_fmt
  13: rustc::util::bug::bug_fmt
  14: rustc::traits::coherence::ty_is_local_constructor
  15: rustc::traits::coherence::ty_is_local
  16: rustc::traits::coherence::orphan_check_trait_ref
  17: rustc::traits::coherence::orphan_check
  18: <rustc_typeck::coherence::orphan::OrphanChecker<'cx, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'v>>::visit_item
  19: rustc::hir::Crate::visit_all_item_likes
  20: rustc_typeck::check_crate::{{closure}}::{{closure}}
  21: rustc_typeck::check_crate
  22: rustc::ty::context::tls::enter_context
  23: <std::thread::local::LocalKey<T>>::with
  24: rustc::ty::context::TyCtxt::create_and_enter
  25: rustc_driver::driver::compile_input
  26: rustc_driver::run_compiler_with_pool
  27: syntax::with_globals
  28: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  29: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  30: rustc_driver::run
  31: rustc_driver::main
  32: std::rt::lang_start::{{closure}}
  33: std::panicking::try::do_call
             at libstd/rt.rs:59
             at libstd/panicking.rs:310
  34: __rust_maybe_catch_panic
             at libpanic_unwind/lib.rs:105
  35: std::rt::lang_start_internal
             at libstd/panicking.rs:289
             at libstd/panic.rs:392
             at libstd/rt.rs:58
  36: main
  37: __libc_start_main
  38: <unknown>
query stack during panic:
end of query stack
error: aborting due to previous error


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 (d5a448b3f 2018-08-13) 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.
@mbrubeck mbrubeck added the I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ label Aug 17, 2018
@oli-obk oli-obk self-assigned this Jan 25, 2019
@oli-obk oli-obk added the T-lang Relevant to the language team, which will review and decide on the PR/issue. label Mar 18, 2019
@oli-obk
Copy link
Contributor

oli-obk commented Mar 18, 2019

@rust-lang/lang How should this ICE be fixed? Do we want to support implementing traits for existential types? Right now existential types just hide the concrete type. Not sure if the use case for extending it exists.

It also seems odd that a single type may have two completely different implementations of a trait, but one of the implementations is indirect via an existential type.

Just an implementation detail, but allowing this will also make codegen more complex, as currently it just assumes that any mention of an existential type or impl Trait type can just as well be the concrete type. For trait resolution that won't be true anymore. E.g. the following code will ICE in codegen because there's no MyEq impl for u32 (codegen searching for that implementation at all is wrong, but expected as per the current way opaque types are handled in codegen).

#![feature(existential_type)]

trait MyEq {
    fn my_eq(&self, other: &Self) -> bool;
}

existential type Bar: PartialEq + Eq;

fn bazr(x: u32) -> Bar {
    x
}

impl MyEq for Bar {
    fn my_eq(&self, other: &Self) -> bool {
        self == other
    }
}

fn main() {
    let x = bazr(42);
    let y = bazr(99);
    let z = bazr(42);
    assert!(x.my_eq(&z));
    assert!(!x.my_eq(&y));
    assert!(z.my_eq(&x));
}

@Centril
Copy link
Contributor

Centril commented Mar 18, 2019

@rust-lang/lang How should this ICE be fixed? Do we want to support implementing traits for existential types? Right now existential types just hide the concrete type.

The RFC notes that:

One last difference between existential type aliases and normal type aliases is that existential type aliases cannot be used in impl blocks:

So impl Eq for Bar {} should result in an error.

Not sure if the use case for extending it exists.

Probably a matter of convenience most of the time...

@jonas-schievink jonas-schievink added A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. and removed T-lang Relevant to the language team, which will review and decide on the PR/issue. labels Aug 6, 2019
@DutchGhost
Copy link
Contributor Author

DutchGhost commented Oct 13, 2019

Existential types aren't really a thing anymore, so the example code above fails to compile.

However, this compiles now:

#![feature(type_alias_impl_trait)]

trait MyTrait {}

impl MyTrait for () {}

type Bar = impl MyTrait;

impl MyTrait for Bar {}

fn bazr() -> Bar { }

fn main() {}

Im not sure this should be allowed.

@Centril
Copy link
Contributor

Centril commented Oct 13, 2019

cc @Aaron1011 @nikomatsakis

@Centril
Copy link
Contributor

Centril commented Oct 13, 2019

@DutchGhost can you file that as a new issue (and close this one)?

@DutchGhost
Copy link
Contributor Author

Closing this in favor of #65384

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-impl-trait Area: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch. C-bug Category: This is a bug. I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants