1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
|
#![feature(type_alias_impl_trait)]
mod foo {
use super::Equals;
pub type WithLifetime<'a> = impl Equals<SelfType = ()>;
fn _defining_use<'a>() -> WithLifetime<'a> {}
}
use foo::WithLifetime;
trait Convert<'a> {
type Witness;
fn convert<'b, T: ?Sized>(_proof: &'b Self::Witness, x: &'a T) -> &'b T;
}
impl<'a> Convert<'a> for () {
type Witness = WithLifetime<'a>;
fn convert<'b, T: ?Sized>(_proof: &'b WithLifetime<'a>, x: &'a T) -> &'b T {
// compiler used to think it gets to assume 'a: 'b here because
// of the `&'b WithLifetime<'a>` argument
x
//~^ ERROR lifetime may not live long enough
}
}
fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
WithLifetime::<'a>::convert_helper::<(), T>(&(), x)
}
trait Equals {
type SelfType;
fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
proof: &'b Self::SelfType,
x: &'a T,
) -> &'b T;
}
impl<S> Equals for S {
type SelfType = Self;
fn convert_helper<'a, 'b, W: Convert<'a, Witness = Self>, T: ?Sized>(
proof: &'b Self,
x: &'a T,
) -> &'b T {
W::convert(proof, x)
}
}
fn main() {
let r;
{
let x = String::from("Hello World?");
r = extend_lifetime(&x);
}
println!("{}", r);
}
|