]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/associated-types-project-from-type-param-via-bound-in-where.rs
Merge commit 'd3a2366ee877075c59b38bd8ced55f224fc7ef51' into sync_cg_clif-2022-07-26
[rust.git] / src / test / ui / associated-types / associated-types-project-from-type-param-via-bound-in-where.rs
1 // run-pass
2 // Various uses of `T::Item` syntax where the bound that supplies
3 // `Item` originates in a where-clause, not the declaration of
4 // `T`. Issue #20300.
5
6 use std::marker::{PhantomData};
7 use std::sync::atomic::{AtomicUsize};
8 use std::sync::atomic::Ordering::SeqCst;
9
10 static COUNTER: AtomicUsize = AtomicUsize::new(0);
11
12 // Preamble.
13 trait Trait { type Item; }
14 struct Struct;
15 impl Trait for Struct {
16     type Item = u32;
17 }
18
19 // Where-clause attached on the method which declares `T`.
20 struct A;
21 impl A {
22     fn foo<T>(_x: T::Item) where T: Trait {
23         COUNTER.fetch_add(1, SeqCst);
24     }
25 }
26
27 // Where-clause attached on the method to a parameter from the struct.
28 struct B<T>(PhantomData<T>);
29 impl<T> B<T> {
30     fn foo(_x: T::Item) where T: Trait {
31         COUNTER.fetch_add(10, SeqCst);
32     }
33 }
34
35 // Where-clause attached to free fn.
36 fn c<T>(_: T::Item) where T : Trait {
37     COUNTER.fetch_add(100, SeqCst);
38 }
39
40 // Where-clause attached to defaulted and non-defaulted trait method.
41 trait AnotherTrait {
42     fn method<T>(&self, _: T::Item) where T: Trait;
43     fn default_method<T>(&self, _: T::Item) where T: Trait {
44         COUNTER.fetch_add(1000, SeqCst);
45     }
46 }
47 struct D;
48 impl AnotherTrait for D {
49     fn method<T>(&self, _: T::Item) where T: Trait {
50         COUNTER.fetch_add(10000, SeqCst);
51     }
52 }
53
54 // Where-clause attached to trait and impl containing the method.
55 trait YetAnotherTrait<T>
56     where T : Trait
57 {
58     fn method(&self, _: T::Item);
59     fn default_method(&self, _: T::Item) {
60         COUNTER.fetch_add(100000, SeqCst);
61     }
62 }
63 struct E<T>(PhantomData<T>);
64 impl<T> YetAnotherTrait<T> for E<T>
65     where T : Trait
66 {
67     fn method(&self, _: T::Item) {
68         COUNTER.fetch_add(1000000, SeqCst);
69     }
70 }
71
72 // Where-clause attached to inherent impl containing the method.
73 struct F<T>(PhantomData<T>);
74 impl<T> F<T> where T : Trait {
75     fn method(&self, _: T::Item) {
76         COUNTER.fetch_add(10000000, SeqCst);
77     }
78 }
79
80 // Where-clause attached to struct.
81 #[allow(dead_code)]
82 struct G<T> where T : Trait {
83     data: T::Item,
84     phantom: PhantomData<T>,
85 }
86
87 fn main() {
88     A::foo::<Struct>(22);
89     B::<Struct>::foo(22);
90     c::<Struct>(22);
91     D.method::<Struct>(22);
92     D.default_method::<Struct>(22);
93     E(PhantomData::<Struct>).method(22);
94     E(PhantomData::<Struct>).default_method(22);
95     F(PhantomData::<Struct>).method(22);
96     G::<Struct> { data: 22, phantom: PhantomData };
97     assert_eq!(COUNTER.load(SeqCst), 11111111);
98 }