| // A test exploiting the bug behind #25860 except with | 
 | // implied trait bounds which currently don't exist. | 
 | use std::marker::PhantomData; | 
 | struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>) | 
 | where | 
 |     T: Convert<'a, 'b>; | 
 |  | 
 | trait Convert<'a, 'b>: Sized { | 
 |     fn cast(&'a self) -> &'b Self; | 
 | } | 
 | impl<'long: 'short, 'short, T> Convert<'long, 'short> for T { | 
 |     fn cast(&'long self) -> &'short T { | 
 |         self | 
 |     } | 
 | } | 
 |  | 
 | // This function will compile once we add implied trait bounds. | 
 | // | 
 | // If we're not careful with our impl, the transformations | 
 | // in `bad` would succeed, which is unsound ✨ | 
 | // | 
 | // FIXME: the error is pretty bad, this should say | 
 | // | 
 | //     `T: Convert<'in_, 'out>` is not implemented | 
 | // | 
 | // help: needed by `Foo<'in_, 'out, T>` | 
 | // | 
 | // Please ping @lcnr if your changes end up causing `badboi` to compile. | 
 | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T { | 
 |     //~^ ERROR lifetime mismatch | 
 |     sadness.cast() | 
 |     //~^ ERROR may not live long enough | 
 | } | 
 |  | 
 | fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) { | 
 |     //~^ ERROR lifetime mismatch | 
 |     let _: &'out T = sadness.cast(); | 
 |     //~^ ERROR may not live long enough | 
 | } | 
 |  | 
 | fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) { | 
 |     //~^ ERROR lifetime mismatch | 
 |     let _: &'out T = sadness.cast(); | 
 |     //~^ ERROR may not live long enough | 
 | } | 
 |  | 
 | fn bad<'short, T>(value: &'short T) -> &'static T { | 
 |     let x: for<'in_, 'out> fn(Foo<'in_, 'out, T>, &'in_ T) -> &'out T = badboi; | 
 |     let x: for<'out> fn(Foo<'short, 'out, T>, &'short T) -> &'out T = x; | 
 |     let x: for<'out> fn(Foo<'static, 'out, T>, &'short T) -> &'out T = x; | 
 |     let x: fn(Foo<'static, 'static, T>, &'short T) -> &'static T = x; | 
 |     x(Foo(PhantomData), value) | 
 | } | 
 |  | 
 | // Use `bad` to cause a segfault. | 
 | fn main() { | 
 |     let mut outer: Option<&'static u32> = Some(&3); | 
 |     let static_ref: &'static &'static u32 = match outer { | 
 |         Some(ref reference) => bad(reference), | 
 |         None => unreachable!(), | 
 |     }; | 
 |     outer = None; | 
 |     println!("{}", static_ref); | 
 | } |