Skip to content
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 compiler panics on type inference when using proc macro (stable) #55765

Closed
RustyYato opened this issue Nov 7, 2018 · 5 comments
Closed
Labels
A-inference Area: Type inference A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-traits Area: Trait system 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

@RustyYato
Copy link
Contributor

RustyYato commented Nov 7, 2018

I was working on yet another implementation of the builder pattern, and pushing the type system to hold info about whether a type has been initialized. I used a proc macro to handle the boiler plate code. When I was testing it I ran into this ICE.

The code I wrote should fail to compile, but it shouldn't cause an ICE.

I tried creating a minimal example, but when I inline the macro call, the ICE disappears.

#[macro_use]
extern crate partial_init_derive;
extern crate partial_init_core;

#[derive(PartialInit)]
struct Foo<T> {
    thing: (T,),
}

fn main() {
    let foo = <Foo<_> as partial_init_core::PartialInit>::uninit().build();
}

note removing type inference by changing main to the code below, also gets rid of hte ICE.

fn main() {
    let foo = <Foo<()> as partial_init_core::PartialInit>::uninit().build();
}

The PartialInit derive macro creates this code (comments have been stripped for brevity):

#[allow(non_camel_case_types)]
mod __Foo__ {
    pub enum thing {}
    impl ::partial_init_core::FieldName for thing {}
    pub mod uninit {
        use super::super::*;
        pub type thing<T> = ::partial_init_core::Uninit<super::thing, T>;
    }
}

#[allow(non_camel_case_types)]
#[derive(Clone, Copy)]
struct PartialFoo<T, thing: ::partial_init_core::MaybeInit<__Foo__::thing, T>> {
    thing: thing,
    __phantom_data__partial_init_: ::partial_init_core::PhantomData<(T)>,
}

#[allow(non_camel_case_types)]
impl<T> ::partial_init_core::PartialInit for Foo<T> {
    type Uninitialized = PartialFoo<T, ::partial_init_core::Uninit<__Foo__::thing, T>>;

    #[inline(always)]
    fn uninit() -> Self::Uninitialized {
        Default::default()
    }
}

impl<T> Default for PartialFoo<T, ::partial_init_core::Uninit<__Foo__::thing, T>> {
    #[inline(always)]
    fn default() -> Self {
        PartialFoo {
            __phantom_data__partial_init_: Default::default(),
            thing: Default::default(),
        }
    }
}
#[allow(non_camel_case_types)]
impl<T, thing: ::partial_init_core::Init<__Foo__::thing, T>> PartialFoo<T, thing> {
    #[inline(always)]
    fn build(self) -> Foo<T> {
        Foo {
            thing: ::partial_init_core::Init::get(self.thing),
        }
    }
}

#[allow(non_camel_case_types)]
impl<T> PartialFoo<T, ::partial_init_core::Uninit<__Foo__::thing, T>> {
    #[inline(always)]
    fn thing<thing: ::partial_init_core::Init<__Foo__::thing, T>>(
        self,
        thing: thing,
    ) -> PartialFoo<T, thing> {
        PartialFoo {
            __phantom_data__partial_init_: Default::default(),
            thing,
        }
    }
}

And the relevant code can be seen here.

the run crate contains the test code
the partial-init-core contains necessary traits and structs for partial-init-derive
the partial-init-derive crate contains the proc-macro

stack trace

error: internal compiler error: librustc\traits\select.rs:3189: Impl DefId(10/0:33 ~ partial_init_core[903a]::init_impl[0]::{{impl}}[4]) was matchable against Obligation(predicate=Binder(TraitPredicate(<partial_init_core::Uninit<__Foo__::thing, (_,)> as partial_init_core::Init<__Foo__::thing, (_,)>>)),depth=0) but now is not

thread 'main' panicked at 'Box<Any>', librustc_errors\lib.rs:587:9
stack backtrace:
   0: <std::sys::windows::args::Args as core::ops::drop::Drop>::drop
   1: <std::path::PathBuf as core::convert::From<std::ffi::os_str::OsString>>::from
   2: std::panicking::take_hook
   3: std::panicking::take_hook
   4: <rustc::ty::sty::Binder<rustc::ty::ProjectionPredicate<'tcx>> as rustc::ty::ToPredicate<'tcx>>::to_predicate
   5: std::panicking::rust_panic_with_hook
   6: <rustc_errors::diagnostic::SubDiagnostic as core::fmt::Debug>::fmt
   7: rustc_errors::Handler::bug
   8: rustc::ty::context::tls::track_diagnostic
   9: rustc::ty::context::tls::track_diagnostic
  10: rustc::ty::context::tls::track_diagnostic
  11: rustc::ty::context::tls::track_diagnostic
  12: rustc::util::bug::bug_fmt
  13: rustc::util::bug::bug_fmt
  14: rustc::infer::InferCtxt::commit_from
  15: rustc::traits::select::SelectionContext::coinductive_predicate
  16: rustc::traits::select::SelectionContext::select
  17: rustc::ty::context::TypeckTables::expr_ty
  18: <rustc::traits::fulfill::FulfillmentContext<'tcx> as rustc::traits::engine::TraitEngine<'tcx>>::select_where_possible
  19: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  20: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  21: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  22: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  23: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  24: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  25: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  26: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  27: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  28: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  29: <rustc_typeck::check::GatherLocalsVisitor<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_pat
  30: <rustc_typeck::check::method::suggest::TraitInfo as core::cmp::PartialOrd>::partial_cmp
  31: <rustc_typeck::astconv::Bounds<'tcx> as core::fmt::Debug>::fmt
  32: <rustc_typeck::check::CheckItemTypesVisitor<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'tcx>>::visit_item
  33: <rustc::traits::query::dropck_outlives::DropckOutlivesResult<'a> as rustc::ty::context::Lift<'tcx>>::lift_to_tcx
  34: rustc::ty::query::on_disk_cache::__ty_decoder_impl::<impl serialize::serialize::Decoder for rustc::ty::query::on_disk_cache::CacheDecoder<'a, 'tcx, 'x>>::read_str
  35: rustc::ty::context::tls::track_diagnostic
  36: rustc::dep_graph::graph::DepGraph::assert_ignored
  37: rustc::ty::context::tls::track_diagnostic
  38: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  39: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  40: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  41: <rustc_typeck::check::CheckItemTypesVisitor<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'tcx>>::visit_item
  42: rustc::ty::query::on_disk_cache::__ty_decoder_impl::<impl serialize::serialize::Decoder for rustc::ty::query::on_disk_cache::CacheDecoder<'a, 'tcx, 'x>>::read_str
  43: rustc::ty::context::tls::track_diagnostic
  44: rustc::dep_graph::graph::DepGraph::assert_ignored
  45: rustc::ty::context::tls::track_diagnostic
  46: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  47: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  48: rustc_typeck::check_crate
  49: <unknown>
  50: <rustc_driver::pretty::NoAnn<'hir> as rustc_driver::pretty::HirPrinterSupport<'hir>>::sess
  51: <rustc_driver::CompilationFailure as core::fmt::Debug>::fmt
  52: rustc_driver::driver::compile_input
  53: rustc_driver::run_compiler
  54: rustc_driver::target_features::add_configuration
  55: rustc_driver::run_compiler
  56: rustc_driver::target_features::add_configuration
  57: _rust_maybe_catch_panic
  58: rustc_driver::profile::dump
  59: rustc_driver::main
  60: <unknown>
  61: std::panicking::update_panic_count
  62: _rust_maybe_catch_panic
  63: std::rt::lang_start_internal
  64: <unknown>
  65: <unknown>
  66: BaseThreadInitThunk
  67: RtlUserThreadStart
query stack during panic:
#0 [typeck_tables_of] processing `main`
#1 [typeck_item_bodies] type-checking all item bodies
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 (da5f414c2 2018-10-24) running on x86_64-pc-windows-msvc

note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin

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

error: Could not compile `run`.
@RustyYato
Copy link
Contributor Author

RustyYato commented Nov 7, 2018

This is the minimal set of impls for the traits in partial_init_core that create the ICE:

impl<U: FieldName, T> MaybeInit<U, T> for Uninit<U, T> {
    #[inline(always)]
    fn get(self) -> Option<T> {
        None
    }
}

impl<U: FieldName, T> MaybeInit<U, (T,)> for T {
    #[inline(always)]
    fn get(self) -> Option<(T,)> {
        Some(Init::<U, (T,)>::get(self))
    }
}

impl<U: FieldName, T> Init<U, (T,)> for T {
    #[inline(always)]
    fn get(self) -> (T,) {
        (self,)
    }
}

@estebank estebank added I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️ A-traits Area: Trait system labels Nov 7, 2018
@RustyYato RustyYato changed the title ICE compiler panics on trait resolution when used with proc macro (stable) ICE compiler panics on type inference when used with proc macro (stable) Nov 7, 2018
@RustyYato RustyYato changed the title ICE compiler panics on type inference when used with proc macro (stable) ICE compiler panics on type inference when using proc macro (stable) Nov 7, 2018
@RustyYato
Copy link
Contributor Author

RustyYato commented Nov 7, 2018

On the most recent nightly (as of this comment), this is also an ICE, but the stack trace changes to

error: internal compiler error: librustc\traits\select.rs:3554: Impl DefId(10/0:12 ~ partial_init_core[9adf]::init_impl[0]::{{impl}}[3]) was matchable against Obligation(predicate=Binder(TraitPredicate(<partial_init_core::Uninit<__Foo__::thing, (_,)> as partial_init_core::Init<__Foo__::thing, (_,)>>)),depth=0) but now is not

thread 'main' panicked at 'Box<Any>', librustc_errors\lib.rs:600:9
stack backtrace:
   0: <std::future::SetOnDrop as core::ops::drop::Drop>::drop
   1: std::panicking::take_hook
   2: std::panicking::take_hook
   3: rustc::ty::structural_impls::<impl rustc::ty::context::Lift<'tcx> for rustc::ty::instance::InstanceDef<'a>>::lift_to_tcx
   4: std::panicking::rust_panic_with_hook
   5: <rustc_errors::diagnostic::SubDiagnostic as core::fmt::Debug>::fmt
   6: rustc_errors::Handler::bug
   7: rustc::ty::context::tls::track_diagnostic
   8: rustc::ty::context::tls::track_diagnostic
   9: rustc::ty::context::tls::track_diagnostic
  10: rustc::ty::context::tls::track_diagnostic
  11: rustc::util::bug::bug_fmt
  12: rustc::util::bug::bug_fmt
  13: rustc::infer::InferCtxt::commit_from
  14: rustc::traits::select::SelectionContext::coinductive_predicate
  15: rustc::traits::select::SelectionContext::select
  16: <rustc::util::ppaux::PrintContext as core::fmt::Debug>::fmt
  17: <rustc::traits::fulfill::FulfillmentContext<'tcx> as rustc::traits::engine::TraitEngine<'tcx>>::select_where_possible
  18: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  19: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  20: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  21: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  22: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  23: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  24: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  25: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  26: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  27: <rustc_typeck::check::FnCtxt<'a, 'gcx, 'tcx> as rustc_typeck::astconv::AstConv<'gcx, 'tcx>>::record_ty
  28: <rustc_typeck::check::GatherLocalsVisitor<'a, 'gcx, 'tcx> as rustc::hir::intravisit::Visitor<'gcx>>::visit_pat
  29: <rustc_typeck::namespace::Namespace as core::fmt::Debug>::fmt
  30: <rustc_typeck::check::method::CandidateSource as core::fmt::Debug>::fmt
  31: <rustc_typeck::check::CheckItemTypesVisitor<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'tcx>>::visit_item
  32: <rustc::traits::query::type_op::subtype::Subtype<'tcx> as core::fmt::Debug>::fmt
  33: rustc::ty::context::tls::track_diagnostic
  34: rustc::ty::context::tls::track_diagnostic
  35: rustc::dep_graph::graph::DepGraph::assert_ignored
  36: rustc::ty::context::tls::track_diagnostic
  37: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  38: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  39: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  40: <rustc_typeck::check::method::CandidateSource as core::fmt::Debug>::fmt
  41: <rustc_typeck::check::CheckItemTypesVisitor<'a, 'tcx> as rustc::hir::itemlikevisit::ItemLikeVisitor<'tcx>>::visit_item
  42: rustc::ty::context::tls::track_diagnostic
  43: rustc::ty::context::tls::track_diagnostic
  44: rustc::dep_graph::graph::DepGraph::assert_ignored
  45: rustc::ty::context::tls::track_diagnostic
  46: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  47: rustc::ty::query::plumbing::<impl rustc::ty::context::TyCtxt<'a, 'gcx, 'tcx>>::try_print_query_stack
  48: rustc_typeck::check_crate
  49: <rustc_driver::pretty::IdentifiedAnnotation<'hir> as rustc_driver::pretty::HirPrinterSupport<'hir>>::sess
  50: <rustc_driver::pretty::IdentifiedAnnotation<'hir> as rustc_driver::pretty::HirPrinterSupport<'hir>>::sess
  51: <rustc_driver::pretty::IdentifiedAnnotation<'hir> as rustc_driver::pretty::HirPrinterSupport<'hir>>::sess
  52: rustc_driver::driver::compile_input
  53: rustc_driver::run_compiler
  54: <rustc_driver::profile::trace::Query as core::fmt::Debug>::fmt
  55: rustc_driver::run_compiler
  56: <humantime::date::Error as std::error::Error>::cause
  57: _rust_maybe_catch_panic
  58: rustc_driver::profile::dump
  59: rustc_driver::main
  60: <unknown>
  61: std::panicking::update_panic_count
  62: _rust_maybe_catch_panic
  63: std::rt::lang_start_internal
  64: <unknown>
  65: <unknown>
  66: BaseThreadInitThunk
  67: RtlUserThreadStart
query stack during panic:
#0 [typeck_tables_of] processing `main`
#1 [typeck_item_bodies] type-checking all item bodies
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.32.0-nightly (15d770400 2018-11-06) running on x86_64-pc-windows-msvc

note: compiler flags: -C debuginfo=2 -C incremental --crate-type bin

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

error: Could not compile `run`.

@RustyYato
Copy link
Contributor Author

RustyYato commented Nov 7, 2018

@estebank could you add a type-inference label, as I think that type inference is where the compiler is going wrong.

--edit--
thanks!

@estebank estebank added the A-inference Area: Type inference label Nov 7, 2018
@jonas-schievink jonas-schievink added A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 6, 2019
@Enselic
Copy link
Member

Enselic commented Jul 26, 2023

Can you still reproduce this? I tried a bit but could not reproduce.

@RustyYato
Copy link
Contributor Author

Yep, looks like it's fixed on the latest stable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-inference Area: Type inference A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) A-traits Area: Trait system 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

4 participants