Description
struct Foo<T>(T); // `T` is covariant.
fn foo<'b>(x: Foo<for<'a> fn(&'a ())>) {
let Foo(y): Foo<fn(&'b ())> = x;
}
fn main() {}
should compile but errors with
error[E0308]: mismatched types
--> src/main.rs:4:13
|
4 | let Foo(y): Foo<fn(&'b ())> = x;
| ^ one type is more general than the other
|
= note: expected fn pointer `for<'a> fn(&'a ())`
found fn pointer `fn(&())`
looking at the mir of foo
it becomes clear why that happens:
fn foo(_1: Foo<for<'a> fn(&'a ())>) -> () {
debug x => _1; // in scope 0 at src/main.rs:3:12: 3:13
let mut _0: (); // return place in scope 0 at src/main.rs:3:40: 3:40
let _2: fn(&()) as UserTypeProjection { base: UserType(0), projs: [Field(field[0], ())] }; // in scope 0 at src/main.rs:4:13: 4:14
scope 1 {
debug y => _2; // in scope 1 at src/main.rs:4:13: 4:14
}
bb0: {
AscribeUserType(_1, +, UserTypeProjection { base: UserType(1), projs: [] }); // scope 0 at src/main.rs:4:17: 4:32
StorageLive(_2); // scope 0 at src/main.rs:4:13: 4:14
_2 = (_1.0: fn(&())); // scope 0 at src/main.rs:4:13: 4:14
_0 = const (); // scope 0 at src/main.rs:3:40: 5:2
StorageDead(_2); // scope 0 at src/main.rs:5:1: 5:2
return; // scope 0 at src/main.rs:5:2: 5:2
}
}
notice that in _2 = (_1.0: fn(&()));
the type of _1.0
is actually for<'a> fn(&'a ())
.
Possible ways to fix this are:
- correctly deal with subtyping when sanitizing field projections, note that they cannot just always be covariant.
- change the type of the field to be the actual one during mir building, so that subtyping actually happens at the assignment
always lazily recompute the type of the field instead of storing it in the mir
Metadata
Metadata
Assignees
Labels
Area: Variance (https://doc.rust-lang.org/nomicon/subtyping.html)Category: This is a bug.Call for participation: Hard difficulty. Experience needed to fix: A lot.Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.Relevant to the types team, which will review and decide on the PR/issue.
Activity
lcnr commentedon Apr 28, 2022
@rustbot claim
intend to work on this myself
lcnr commentedon Apr 29, 2022
also add a test for
lcnr commentedon Oct 21, 2022
That's imo the correct solution. Open to mentor someone here, ideally with some experience with working with
ty::Ty
and mir building.If you're interested and need help, contact me on zulip and we can either chat about it there or on zoom.
b-naber commentedon Oct 21, 2022
@rustbot claim
24 remaining items