Skip to content

ICE when combining GATs and HRTBs #76826

Closed
@zesterer

Description

@zesterer

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(<[[email protected]:41:19: 41:50] as std::ops::FnMut<(<Windows<i32> as Iter>::Item<'_>,)>>), Binder(<[[email protected]:41:19: 41:50] as std::ops::FnMut<(&mut [i32],)>>), Sorts(ExpectedFound { expected: &mut [i32], found: <Windows<i32> as Iter>::Item<'_> }))` selecting `Binder(<[[email protected]: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 `<[[email protected]: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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-GATsArea: Generic associated types (GATs)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