Open
Description
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