// run-pass // Various uses of `T::Item` syntax where the bound that supplies // `Item` originates in a where-clause, not the declaration of // `T`. Issue #20300. use std::marker::{PhantomData}; use std::sync::atomic::{AtomicUsize}; use std::sync::atomic::Ordering::SeqCst; static COUNTER: AtomicUsize = AtomicUsize::new(0); // Preamble. trait Trait { type Item; } struct Struct; impl Trait for Struct { type Item = u32; } // Where-clause attached on the method which declares `T`. struct A; impl A { fn foo(_x: T::Item) where T: Trait { COUNTER.fetch_add(1, SeqCst); } } // Where-clause attached on the method to a parameter from the struct. struct B(PhantomData); impl B { fn foo(_x: T::Item) where T: Trait { COUNTER.fetch_add(10, SeqCst); } } // Where-clause attached to free fn. fn c(_: T::Item) where T : Trait { COUNTER.fetch_add(100, SeqCst); } // Where-clause attached to defaulted and non-defaulted trait method. trait AnotherTrait { fn method(&self, _: T::Item) where T: Trait; fn default_method(&self, _: T::Item) where T: Trait { COUNTER.fetch_add(1000, SeqCst); } } struct D; impl AnotherTrait for D { fn method(&self, _: T::Item) where T: Trait { COUNTER.fetch_add(10000, SeqCst); } } // Where-clause attached to trait and impl containing the method. trait YetAnotherTrait where T : Trait { fn method(&self, _: T::Item); fn default_method(&self, _: T::Item) { COUNTER.fetch_add(100000, SeqCst); } } struct E(PhantomData); impl YetAnotherTrait for E where T : Trait { fn method(&self, _: T::Item) { COUNTER.fetch_add(1000000, SeqCst); } } // Where-clause attached to inherent impl containing the method. struct F(PhantomData); impl F where T : Trait { fn method(&self, _: T::Item) { COUNTER.fetch_add(10000000, SeqCst); } } // Where-clause attached to struct. #[allow(dead_code)] struct G where T : Trait { data: T::Item, phantom: PhantomData, } fn main() { A::foo::(22); B::::foo(22); c::(22); D.method::(22); D.default_method::(22); E(PhantomData::).method(22); E(PhantomData::).default_method(22); F(PhantomData::).method(22); G:: { data: 22, phantom: PhantomData }; assert_eq!(COUNTER.load(SeqCst), 11111111); }