Closed
Description
Consider this:
fn new_vec<T>() -> Vec<&'static T> { Vec::new() }
fn foo<'a, T>() {
// Errors, as it cannot coerce Vec<T> to Vec<U> where U <: T.
let _: Vec<&'a T> = new_vec();
}
This can lead to the need to make functions generic over lifetimes in their return type, but that doesn't work so well when referencing a static
(which cannot be generic over non-'static
lifetimes like function can).
To show that this is not specific to Vec
(or other unsafe-using abstractions):
struct Foo<T>(T);
fn new_foo<T>() -> Foo<&'static T> { fail!() }
fn foo<'a, T>() {
// Same error, Foo<T> is also invariant w.r.t T.
let _: Foo<&'a T> = new_foo();
}
Without the Foo
newtype, it works as expected:
fn new_foo<T: 'static>() -> &'static T { fail!() }
fn foo<'a, T: 'static>() {
let _: &'a T = new_foo();
}
It also works when the variance comes from a lifetime parameter:
struct Foo<'a, T: 'a>(&'a T);
fn new_foo<T: 'static>() -> Foo<'static, T> { fail!() }
fn foo<'a, T: 'static>() {
let _: Foo<'a, T> = new_foo();
}
The now-closed (awaiting a rewrite) rust-lang/rfcs#233 RFC PR would fix this.
cc @nikomatsakis
Metadata
Metadata
Assignees
Labels
No labels