]> git.lizzy.rs Git - rust.git/blob - src/test/ui/impl-trait/bound-normalization-pass.rs
Auto merge of #62542 - Centril:rollup-5mpb8tu, r=Centril
[rust.git] / src / test / ui / impl-trait / bound-normalization-pass.rs
1 // check-pass
2 // edition:2018
3
4 #![feature(async_await)]
5 #![feature(existential_type)]
6 #![feature(impl_trait_in_bindings)]
7 //~^ WARNING the feature `impl_trait_in_bindings` is incomplete
8
9 // See issue 60414
10
11 /////////////////////////////////////////////
12 // Reduction to `impl Trait`
13
14 struct Foo<T>(T);
15
16 trait FooLike { type Output; }
17
18 impl<T> FooLike for Foo<T> {
19     type Output = T;
20 }
21
22 mod impl_trait {
23     use super::*;
24
25     trait Trait {
26         type Assoc;
27     }
28
29     /// `T::Assoc` should be normalized to `()` here.
30     fn foo_pass<T: Trait<Assoc=()>>() -> impl FooLike<Output=T::Assoc> {
31         Foo(())
32     }
33 }
34
35 /////////////////////////////////////////////
36 // Same with lifetimes in the trait
37
38 mod lifetimes {
39     use super::*;
40
41     trait Trait<'a> {
42         type Assoc;
43     }
44
45     /// Like above.
46     ///
47     /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
48     fn foo2_pass<'a, T: Trait<'a, Assoc=()> + 'a>(
49     ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a {
50         Foo(())
51     }
52
53     /// Normalization to type containing bound region.
54     ///
55     /// FIXME(#51525) -- the shorter notation `T::Assoc` winds up referencing `'static` here
56     fn foo2_pass2<'a, T: Trait<'a, Assoc=&'a ()> + 'a>(
57     ) -> impl FooLike<Output=<T as Trait<'a>>::Assoc> + 'a {
58         Foo(&())
59     }
60 }
61
62 /////////////////////////////////////////////
63 // Reduction using `impl Trait` in bindings
64
65 mod impl_trait_in_bindings {
66     struct Foo;
67
68     trait FooLike { type Output; }
69
70     impl FooLike for Foo {
71         type Output = u32;
72     }
73
74     trait Trait {
75         type Assoc;
76     }
77
78     fn foo<T: Trait<Assoc=u32>>() {
79         let _: impl FooLike<Output=T::Assoc> = Foo;
80     }
81 }
82
83 /////////////////////////////////////////////
84 // The same applied to `existential type`s
85
86 mod existential_types {
87     trait Implemented {
88         type Assoc;
89     }
90     impl<T> Implemented for T {
91         type Assoc = u8;
92     }
93
94     trait Trait {
95         type Out;
96     }
97
98     impl Trait for () {
99         type Out = u8;
100     }
101
102     existential type Ex: Trait<Out = <() as Implemented>::Assoc>;
103
104     fn define() -> Ex {
105         ()
106     }
107 }
108
109 fn main() {}