Skip to content

Spurious cycle when passing an existential type referencing EnumMap to closure #116380

Open
@amatveiakin

Description

@amatveiakin

This does not compile:

#![feature(type_alias_impl_trait)]
type Element = enum_map::EnumMap<bool, u32>;
type MyIterator<'a> = impl Iterator<Item = &'a Element> + 'a;
fn get_iter(data: &[Element]) -> MyIterator { data.iter() }
fn process_data(data: &[Element], func: impl FnOnce(MyIterator)) {
    func(get_iter(data))
}

Got:

error[E0391]: cycle detected when evaluating trait selection obligation `enum_map::EnumMap<bool, u32>: core::marker::Sized`
  |
  = note: ...which requires revealing opaque types in `[Binder { value: ProjectionPredicate(AliasTy { args: [impl FnOnce(MyIterator)/#0, (Alias(Opaque, AliasTy { args: [ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon })], def_id: DefId(0:8 ~ existential_cycle[bca7]::MyIterator::{opaque#0}) }),)], def_id: DefId(2:3025 ~ core[fb59]::ops::function::FnOnce::Output) }, Term::Ty(())), bound_vars: [Region(BrAnon)] }, Binder { value: TraitPredicate(<impl FnOnce(MyIterator) as core::ops::function::FnOnce<(MyIterator<'_>,)>>, polarity:Positive), bound_vars: [Region(BrAnon)] }, Binder { value: TraitPredicate(<impl FnOnce(MyIterator) as core::marker::Sized>, polarity:Positive), bound_vars: [] }]`...
note: ...which requires computing type of `MyIterator::{opaque#0}`...
 --> src\lib.rs:3:23
  |
3 | type MyIterator<'a> = impl Iterator<Item = &'a Element> + 'a;
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires computing type of opaque `MyIterator::{opaque#0}`...
 --> src\lib.rs:3:23
  |
3 | type MyIterator<'a> = impl Iterator<Item = &'a Element> + 'a;
  |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...which requires type-checking `process_data`...
 --> src\lib.rs:6:19
  |
6 |     func(get_iter(data))
  |                   ^^^^
  = note: ...which again requires evaluating trait selection obligation `enum_map::EnumMap<bool, u32>: core::marker::Sized`, completing the cycle
note: cycle used when checking that `process_data` is well-formed
 --> src\lib.rs:5:23
  |
5 | fn process_data(data: &[Element], func: impl FnOnce(MyIterator)) {
  |                       ^^^^^^^^^^
  = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

For more information about this error, try `rustc --explain E0391`.

Whereas the version without closures compiles fine:

#![feature(type_alias_impl_trait)]
type Element = enum_map::EnumMap<bool, u32>;
type MyIterator<'a> = impl Iterator<Item = &'a Element> + 'a;
fn get_iter(data: &[Element]) -> MyIterator { data.iter() }
fn process_data(data: &[Element]) {       // CHANGED: no closure
    assert!(get_iter(data).count() > 0);  //
}

And so does the version with closures, but without EnumMap:

#![feature(type_alias_impl_trait)]
type Element = [u32; 2];    // CHANGED: another type with the same layout
type MyIterator<'a> = impl Iterator<Item = &'a Element> + 'a;
fn get_iter(data: &[Element]) -> MyIterator { data.iter() }
fn process_data(data: &[Element], func: impl FnOnce(MyIterator)) {
    func(get_iter(data))
}

The Cargo.toml is:

[package]
name = "existential-cycle"
version = "0.1.0"
edition = "2021"

[dependencies]
enum-map = { version = "2.6.3" }

(Sorry, couldn't add a rust playground link, because it doesn't have enum_map.)

I believe the problem lies in rustc rather than enum_map: the fact that EnumMap<bool, u32> is Sized shouldn't depend on the iterator types introduced here.

Meta

rustc 1.75.0-nightly (2e5a9dd 2023-10-02)
binary: rustc
commit-hash: 2e5a9dd
commit-date: 2023-10-02
host: x86_64-pc-windows-msvc
release: 1.75.0-nightly
LLVM version: 17.0.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-closuresArea: Closures (`|…| { … }`)C-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`I-cycleIssue: A query cycle occurred while none was expectedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions