]> git.lizzy.rs Git - rust.git/blob - tests/ui/regions/type-param-outlives-reempty-issue-74429.rs
add UI test + docs for `E0789`
[rust.git] / tests / ui / regions / type-param-outlives-reempty-issue-74429.rs
1 // Regression test for #74429, where we didn't think that a type parameter
2 // outlived `ReEmpty`.
3
4 // check-pass
5
6 use std::marker::PhantomData;
7
8 fn apply<T, F: FnOnce(T)>(_: T, _: F) {}
9
10 #[derive(Clone, Copy)]
11 struct Invariant<T> {
12     t: T,
13     p: PhantomData<fn(T) -> T>,
14 }
15
16 fn verify_reempty<T>(x: T) {
17     // r is inferred to have type `Invariant<&ReEmpty(U0) T>`
18     let r = Invariant { t: &x, p: PhantomData };
19     // Creates a new universe, all variables from now on are in `U1`, say.
20     let _: fn(&()) = |_| {};
21     // Closure parameter is of type `&ReEmpty(U1) T`, so the closure has an implied
22     // bound of `T: ReEmpty(U1)`
23     apply(&x, |_| {
24         // Requires `typeof(r)` is well-formed, i.e. `T: ReEmpty(U0)`. If we
25         // only have the implied bound from the closure parameter to use this
26         // requires `ReEmpty(U1): ReEmpty(U0)`, which isn't true so we reported
27         // an error.
28         //
29         // This doesn't happen any more because we ensure that `T: ReEmpty(U0)`
30         // is an implicit bound for all type parameters.
31         drop(r);
32     });
33 }
34
35 fn main() {}