Skip to content

ICE when combining GATs and HRTBs #76826

Closed

Description

The following code triggers an ICE.

Code

#![feature(generic_associated_types)]

pub trait Iter {
    type Item<'a> where Self: 'a;
    
    fn next<'a>(&'a mut self) -> Option<Self::Item<'a>>;
    
    fn for_each<F>(mut self, mut f: F)
        where Self: Sized, F: for<'a> FnMut(Self::Item<'a>)
    {
        while let Some(item) = self.next() {
            f(item);
        }
    }
}

pub struct Windows<T> {
    items: Vec<T>,
    start: usize,
    len: usize,
}

impl<T> Windows<T> {
    pub fn new(items: Vec<T>, len: usize) -> Self {
        Self { items, start: 0, len }
    }
}

impl<T> Iter for Windows<T> {
    type Item<'a> where T: 'a = &'a mut [T];
    
    fn next<'a>(&'a mut self) -> Option<Self::Item<'a>> {
        let slice = self.items.get_mut(self.start..self.start + self.len)?;
        self.start += 1;
        Some(slice)
    }
}

fn main() {
    Windows::new(vec![1, 2, 3, 4, 5], 3)
        .for_each(|slice| println!("{:?}", slice));
}

Playground version

This example can no doubt be minimised further, but it should be obvious what I'm attempting to do and why. This would be, I assume, a fairly common use-case for GATs and are likely to be essential if GATs are ever to be integrated into Iterator.

Meta

rustc --version --verbose:

rustc 1.48.0-nightly (d006f5734 2020-08-28)

Error output

error: internal compiler error: src/librustc_trait_selection/traits/codegen/mod.rs:75:17: Encountered error `OutputTypeParameterMismatch(Binder(<[closure@gats.rs:41:19: 41:50] as std::ops::FnMut<(<Windows<i32> as Iter>::Item<'_>,)>>), Binder(<[closure@gats.rs:41:19: 41:50] as std::ops::FnMut<(&mut [i32],)>>), Sorts(ExpectedFound { expected: &mut [i32], found: <Windows<i32> as Iter>::Item<'_> }))` selecting `Binder(<[closure@gats.rs:41:19: 41:50] as std::ops::FnMut<(&mut [i32],)>>)` during codegen

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:918:9
Backtrace

stack backtrace:
   0: std::panicking::begin_panic
   1: rustc_errors::HandlerInner::bug
   2: rustc_errors::Handler::bug
   3: rustc_middle::util::bug::opt_span_bug_fmt::{{closure}}
   4: rustc_middle::ty::context::tls::with_opt::{{closure}}
   5: rustc_middle::ty::context::tls::with_opt
   6: rustc_middle::util::bug::opt_span_bug_fmt
   7: rustc_middle::util::bug::bug_fmt
   8: rustc_infer::infer::InferCtxtBuilder::enter
   9: rustc_trait_selection::traits::codegen::codegen_fulfill_obligation
  10: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::codegen_fulfill_obligation>::compute
  11: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  12: rustc_data_structures::stack::ensure_sufficient_stack
  13: rustc_query_system::query::plumbing::get_query_impl
  14: rustc_ty::instance::inner_resolve_instance
  15: rustc_ty::instance::resolve_instance
  16: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::resolve_instance>::compute
  17: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  18: rustc_data_structures::stack::ensure_sufficient_stack
  19: rustc_query_system::query::plumbing::get_query_impl
  20: rustc_middle::ty::instance::Instance::resolve_opt_const_arg
  21: rustc_middle::ty::instance::Instance::resolve
  22: <rustc_mir::monomorphize::collector::MirNeighborCollector as rustc_middle::mir::visit::Visitor>::visit_terminator
  23: rustc_mir::monomorphize::collector::collect_neighbours
  24: rustc_mir::monomorphize::collector::collect_items_rec
  25: rustc_mir::monomorphize::collector::collect_items_rec
  26: rustc_session::utils::<impl rustc_session::session::Session>::time
  27: rustc_mir::monomorphize::collector::collect_crate_mono_items
  28: rustc_mir::monomorphize::partitioning::collect_and_partition_mono_items
  29: rustc_middle::ty::query::<impl rustc_query_system::query::config::QueryAccessors<rustc_middle::ty::context::TyCtxt> for rustc_middle::ty::query::queries::collect_and_partition_mono_items>::compute
  30: rustc_query_system::dep_graph::graph::DepGraph<K>::with_task_impl
  31: rustc_data_structures::stack::ensure_sufficient_stack
  32: rustc_query_system::query::plumbing::get_query_impl
  33: rustc_codegen_ssa::base::codegen_crate
  34: <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::backend::CodegenBackend>::codegen_crate
  35: rustc_interface::passes::QueryContext::enter
  36: rustc_interface::queries::Queries::ongoing_codegen
  37: rustc_interface::queries::<impl rustc_interface::interface::Compiler>::enter
  38: rustc_span::with_source_map
  39: rustc_interface::interface::create_compiler_and_run
  40: scoped_tls::ScopedKey<T>::set
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-compiler&template=ice.md

note: rustc 1.48.0-nightly (d006f5734 2020-08-28) running on x86_64-unknown-linux-gnu

query stack during panic:
#0 [codegen_fulfill_obligation] checking if `std::ops::FnMut` fulfills its obligations
#1 [resolve_instance] resolving instance `<[closure@gats.rs:41:19: 41:50] as std::ops::FnMut<(&mut [i32],)>>::call_mut`
#2 [collect_and_partition_mono_items] collect_and_partition_mono_items
end of query stack
error: aborting due to previous error; 1 warning emitted

Removing the final line (.for_each(|slice| println!("{:?}", slice))) prevents the ICE, implying that this is a codegen issue (as corroborated by the stack trace).

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

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-generic_associated_types`#![feature(generic_associated_types)]` a.k.a. GATsI-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.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions