]> git.proxmox.com Git - rustc.git/blame - src/test/ui/implied-bounds/hrlt-implied-trait-bounds-guard.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / src / test / ui / implied-bounds / hrlt-implied-trait-bounds-guard.rs
CommitLineData
5099ac24
FG
1// A test exploiting the bug behind #25860 except with
2// implied trait bounds which currently don't exist without `-Zchalk`.
3use std::marker::PhantomData;
4struct Foo<'a, 'b, T>(PhantomData<(&'a (), &'b (), T)>)
5where
6 T: Convert<'a, 'b>;
7
8trait Convert<'a, 'b>: Sized {
9 fn cast(&'a self) -> &'b Self;
10}
11impl<'long: 'short, 'short, T> Convert<'long, 'short> for T {
12 fn cast(&'long self) -> &'short T {
13 self
14 }
15}
16
17// This function will compile once we add implied trait bounds.
18//
19// If we're not careful with our impl, the transformations
20// in `bad` would succeed, which is unsound ✨
21//
22// FIXME: the error is pretty bad, this should say
23//
24// `T: Convert<'in_, 'out>` is not implemented
25//
26// help: needed by `Foo<'in_, 'out, T>`
27//
28// Please ping @lcnr if your changes end up causing `badboi` to compile.
29fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) -> &'out T {
30 //~^ ERROR lifetime mismatch
31 sadness.cast()
32}
33
487cf647
FG
34fn badboi2<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ T) {
35 //~^ ERROR lifetime mismatch
36 let _: &'out T = sadness.cast();
37}
38
39fn badboi3<'in_, 'out, T>(a: Foo<'in_, 'out, (&'in_ T, &'out T)>, sadness: &'in_ T) {
40 //~^ ERROR lifetime mismatch
41 let _: &'out T = sadness.cast();
42}
43
5099ac24
FG
44fn bad<'short, T>(value: &'short T) -> &'static T {
45 let x: for<'in_, 'out> fn(Foo<'in_, 'out, T>, &'in_ T) -> &'out T = badboi;
46 let x: for<'out> fn(Foo<'short, 'out, T>, &'short T) -> &'out T = x;
47 let x: for<'out> fn(Foo<'static, 'out, T>, &'short T) -> &'out T = x;
48 let x: fn(Foo<'static, 'static, T>, &'short T) -> &'static T = x;
49 x(Foo(PhantomData), value)
50}
51
52// Use `bad` to cause a segfault.
53fn main() {
54 let mut outer: Option<&'static u32> = Some(&3);
55 let static_ref: &'static &'static u32 = match outer {
56 Some(ref reference) => bad(reference),
57 None => unreachable!(),
58 };
59 outer = None;
60 println!("{}", static_ref);
61}