Skip to content

ICE: Existential type (w/ and w/o NLL) #53598

Closed

Description

@andreytkachenko

here is the example:

#![feature(nll, existential_type)]

pub trait Engine {}
pub trait RenderImplementation<E, CE> 
    where E: Engine,
          CE: Engine,
{
    fn render_impl<C: Renderable<CE>>(&self, eng: &E, children: &C);
}
pub trait Renderable<E> 
    where E: Engine,
{
    fn render(&self, eng: &E);
}
pub trait View<E, CE>
    where E: Engine,
          CE: Engine,
{
    type Renderable: Renderable<E>;

    fn build<C: Renderable<CE> + 'static>(self, children: Option<C>) -> Self::Renderable;
}

pub struct Node <E, I, CHE, CH>
    where 
        E: Engine,
        CHE: Engine,
        I: RenderImplementation<E, CHE>,
        CH: Renderable<CHE>
{
    _m: std::marker::PhantomData<(I, CH, E, CHE)>
}

impl<E, I, CHE, CH> Node<E, I, CHE, CH>
    where 
        E: Engine,
        CHE: Engine,
        I: RenderImplementation<E, CHE>,
        CH: Renderable<CHE>
{
    pub fn new(_item: I, _children: CH) -> Self {
        Self {
            _m: Default::default()
        }
    }
}

impl<E, I, CHE, CH> Renderable<E> for Node<E, I, CHE, CH>
    where 
        E: Engine,
        CHE: Engine,
        I: RenderImplementation<E, CHE>,
        CH: Renderable<CHE>
{
    fn render(&self, _eng: &E) {}
}

impl <E: Engine, T: Renderable<E>> Renderable<E> for Option<T> {
    fn render(&self, _eng: &E) {}
}

pub struct HtmlEngine;
impl Engine for HtmlEngine {}

pub struct Div;

impl RenderImplementation<HtmlEngine, HtmlEngine> for Div {   
    fn render_impl<C>(&self, _eng: &HtmlEngine, _children: &C)
        where C: Renderable<HtmlEngine> 
    {}
}

impl View<HtmlEngine, HtmlEngine> for Div {
    existential type Renderable: Renderable<HtmlEngine>;

    fn build<C: Renderable<HtmlEngine> + 'static>(self, children: Option<C>) -> Self::Renderable {
        Node::new(self, children)
    }
}

fn main() {}

this example will compile well if you remove nll

Activity

  1. matthiaskrgr commented on Aug 22, 2018

    @matthiaskrgr
    Member

    Backtrace:

    
       Compiling issue_53598 v0.1.0 (file:///tmp/issue_53598)
    error: internal compiler error: librustc/ty/subst.rs:479: Type parameter `C/#0` (C/0) out of range when substituting (root type=Some(Node<HtmlEngine, Div, HtmlEngine, std::option::Option<C>>)) substs=[]
    thread 'main' panicked at 'Box<Any>', librustc_errors/lib.rs:517: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::span_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::span_bug_fmt
      14: <rustc::ty::subst::SubstFolder<'a, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
      15: rustc::ty::fold::TypeFoldable::fold_with
      16: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable<'tcx> for &'tcx rustc::ty::TyS<'tcx>>::super_fold_with
      17: <rustc::ty::subst::SubstFolder<'a, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
      18: rustc::ty::fold::TypeFoldable::fold_with
      19: rustc::ty::structural_impls::<impl rustc::ty::fold::TypeFoldable<'tcx> for &'tcx rustc::ty::TyS<'tcx>>::super_fold_with
      20: <rustc::ty::subst::SubstFolder<'a, 'gcx, 'tcx> as rustc::ty::fold::TypeFolder<'gcx, 'tcx>>::fold_ty
      21: rustc::infer::InferCtxt::commit_if_ok
      22: <rustc::traits::query::type_op::custom::CustomTypeOp<F, G> as rustc::traits::query::type_op::TypeOp<'gcx, 'tcx>>::fully_perform
      23: rustc_mir::borrow_check::nll::type_check::type_check
      24: rustc_mir::borrow_check::nll::compute_regions
      25: rustc_mir::borrow_check::do_mir_borrowck
      26: rustc::ty::context::GlobalCtxt::enter_local
      27: rustc_mir::borrow_check::mir_borrowck
      28: rustc::ty::query::__query_compute::mir_borrowck
      29: rustc::ty::query::<impl rustc::ty::query::config::QueryAccessors<'tcx> for rustc::ty::query::queries::mir_borrowck<'tcx>>::compute
      30: rustc::ty::context::tls::with_context
      31: rustc::dep_graph::graph::DepGraph::with_task_impl
      32: <rustc::ty::query::plumbing::JobOwner<'a, 'tcx, Q>>::start
      33: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::force_query_with_job
      34: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::get_query
      35: rustc::ty::query::<impl rustc::ty::context::TyCtxt<'a, 'tcx, 'lcx>>::mir_borrowck
      36: rustc::ty::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::par_body_owners
      37: rustc::util::common::time
      38: rustc::ty::context::tls::enter_context
      39: <std::thread::local::LocalKey<T>>::with
      40: rustc::ty::context::TyCtxt::create_and_enter
      41: rustc_driver::driver::compile_input
      42: rustc_driver::run_compiler_with_pool
      43: syntax::with_globals
      44: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
      45: __rust_maybe_catch_panic
                 at libpanic_unwind/lib.rs:102
      46: rustc_driver::run
      47: rustc_driver::main
      48: std::rt::lang_start::{{closure}}
      49: std::panicking::try::do_call
                 at libstd/rt.rs:59
                 at libstd/panicking.rs:310
      50: __rust_maybe_catch_panic
                 at libpanic_unwind/lib.rs:102
      51: std::rt::lang_start_internal
                 at libstd/panicking.rs:289
                 at libstd/panic.rs:392
                 at libstd/rt.rs:58
      52: main
      53: __libc_start_main
      54: <unknown>
    query stack during panic:
    #0 [mir_borrowck] processing `<Div as View<HtmlEngine, HtmlEngine>>::build`
    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 (33b923fd4 2018-08-18) running on x86_64-unknown-linux-gnu
    note: compiler flags: -C debuginfo=2 -C incremental -C target-cpu=native --crate-type bin
    note: some of the compiler flags provided by cargo are hidden
    error: Could not compile `issue_53598`.
    To learn more, run the command again with --verbose.
    
  2. added
    A-NLLArea: Non-lexical lifetimes (NLL)
    A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.
    on Aug 22, 2018
  3. andreytkachenko commented on Aug 22, 2018

    @andreytkachenko
    ContributorAuthor

    Hmm I reproduced same ICE with next snippet without nll:

    #![feature(existential_type)]
    
    pub trait Engine {}
    pub trait RenderImplementation<E, CE> 
        where E: Engine,
              CE: Engine,
    {
        fn render_impl<C: Renderable<CE>>(&self, eng: &E, children: &C);
    }
    pub trait Renderable<E> 
        where E: Engine,
    {
        fn render(&self, eng: &E);
    }
    pub trait View<E, CE>
        where E: Engine,
              CE: Engine,
    {
        type Renderable: Renderable<E>;
    
        fn build<C: Renderable<CE> + 'static>(self, children: Option<C>) -> Self::Renderable;
    }
    
    pub struct Node <E, I, CHE, CH>
        where 
            E: Engine,
            CHE: Engine,
            I: RenderImplementation<E, CHE>,
            CH: Renderable<CHE>
    {
        _m: std::marker::PhantomData<(I, CH, E, CHE)>
    }
    
    impl<E, I, CHE, CH> Node<E, I, CHE, CH>
        where 
            E: Engine,
            CHE: Engine,
            I: RenderImplementation<E, CHE>,
            CH: Renderable<CHE>
    {
        pub fn new(_item: I, _children: CH) -> Self {
            Self {
                _m: Default::default()
            }
        }
    }
    
    impl<E, I, CHE, CH> Renderable<E> for Node<E, I, CHE, CH>
        where 
            E: Engine,
            CHE: Engine,
            I: RenderImplementation<E, CHE>,
            CH: Renderable<CHE>
    {
        fn render(&self, _eng: &E) {}
    }
    
    impl <E: Engine, T: Renderable<E>> Renderable<E> for Option<T> {
        fn render(&self, _eng: &E) {}
    }
    
    pub struct HtmlEngine;
    impl Engine for HtmlEngine {}
    
    pub struct Div;
    
    impl RenderImplementation<HtmlEngine, HtmlEngine> for Div {   
        fn render_impl<C>(&self, _eng: &HtmlEngine, _children: &C)
            where C: Renderable<HtmlEngine> 
        {}
    }
    
    impl View<HtmlEngine, HtmlEngine> for Div {
        existential type Renderable: Renderable<HtmlEngine>;
    
        fn build<C: Renderable<HtmlEngine> + 'static>(self, children: Option<C>) -> Self::Renderable {
            Node::new(self, children)
        }
    }
    
    #[derive(Default)]
    pub struct Stub<E: Engine> {
        _e: std::marker::PhantomData<E>
    }
    
    impl<E: Engine> Renderable<E> for Stub<E>  {
        fn render(&self, _eng: &E) {}
    }
    
    fn main() {
        Div.build::<Stub<_>>(None);
    }
  4. changed the title [-]ICE: Existential type + NLL [/-] [+]ICE: Existential type [+ NLL] [/+] on Aug 22, 2018
  5. added
    I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
    on Aug 22, 2018
  6. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    and removed
    A-NLLArea: Non-lexical lifetimes (NLL)
    on Aug 27, 2018
  7. changed the title [-]ICE: Existential type [+ NLL] [/-] [+]ICE: Existential type (w/ and w/o NLL)[/+] on Aug 28, 2018
  8. Arnavion commented on Jan 29, 2019

    @Arnavion
    Contributor

    Smaller repro:

    #![feature(existential_type)]
    
    pub trait Foo {
        type Item: std::fmt::Debug;
    
        fn foo<T: std::fmt::Debug>(_: T) -> Self::Item;
    }
    
    #[derive(Debug)]
    pub struct S<T>(std::marker::PhantomData<T>);
    
    pub struct S2;
    
    impl Foo for S2 {
        existential type Item: std::fmt::Debug;
    
        fn foo<T: std::fmt::Debug>(_: T) -> Self::Item {
            S::<T>(Default::default())
        }
    }

    Edit: AFAICT the problem is the existential assoc type is being made dependent on the type parameter of the trait method (<S2 as Foo>::foo's T in this repro, <Div as View<HtmlEngine, HtmlEngine>>::build's C in the OP). So it would be a compile error if it weren't for the ICE.

  9. andreytkachenko commented on Jan 29, 2019

    @andreytkachenko
    ContributorAuthor

    @Arnavion you example compiles without ICE.

  10. andreytkachenko commented on Jan 29, 2019

    @andreytkachenko
    ContributorAuthor

    @Arnavion, sorry it needs to be added nll feature or used 2018 edition.

    Here is complete one which fails to compile regardless nll feature:

    #![feature(existential_type)]
    
    pub trait Foo {
        type Item: std::fmt::Debug;
    
        fn foo<T: std::fmt::Debug>(_: T) -> Self::Item;
    }
    
    #[derive(Debug)]
    pub struct S<T>(std::marker::PhantomData<T>);
    
    pub struct S2;
    
    impl Foo for S2 {
        existential type Item: std::fmt::Debug;
    
        fn foo<T: std::fmt::Debug>(_: T) -> Self::Item {
            S::<T>(Default::default())
        }
    }
    
    fn main() {
        S2::foo(123);
    }
  11. self-assigned this
    on Jan 29, 2019
  12. Arnavion commented on Jan 29, 2019

    @Arnavion
    Contributor

    @andreytkachenko Right, 2015 doesn't hit the error until you actually try to use the type.

    Regardless, as I said in my previous comment, this code should be a compile error anyway regardless of edition, since it's trying to declare an associated type that depends on the type parameters of the trait method rather than the trait.

  13. pnkfelix commented on Mar 6, 2019

    @pnkfelix
    Contributor

    hey @oli-obk, have you had a chance to look into this yet? Do you think you will be looking at it in the near term, or should we unassign you?

  14. 3 remaining items

  15. pnkfelix commented on Mar 14, 2019

    @pnkfelix
    Contributor

    Discussed in T-compiler meeting. This is a blocker for the existential type feature. But there is no schedule yet set for stabilizing that feature. Thus, downgrading fixing this to P-medium.

  16. added and removed
    P-highHigh priority
    on Mar 14, 2019
  17. added
    requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.
    on Jul 28, 2019
  18. Aaron1011 commented on Jul 29, 2019

    @Aaron1011
    Contributor

    This no longer produces an ICE on the latest nightly.

  19. Arnavion commented on Jul 29, 2019

    @Arnavion
    Contributor

    Yes, it was fixed by #62090

  20. added a commit that references this issue on Aug 12, 2019
  21. added a commit that references this issue on Aug 12, 2019
  22. added a commit that references this issue on Aug 12, 2019
  23. added a commit that references this issue on Aug 12, 2019
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.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️P-mediumMedium priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions