-
Notifications
You must be signed in to change notification settings - Fork 13.2k
/
Copy pathassociated-types-project-from-type-param-via-bound-in-where-clause.rs
109 lines (96 loc) · 2.87 KB
/
associated-types-project-from-type-param-via-bound-in-where-clause.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Various uses of `T::Item` syntax where the bound that supplies
// `Item` originates in a where-clause, not the declaration of
// `T`. Issue #20300.
#![feature(const_fn)]
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<T>(_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<T>(PhantomData<T>);
impl<T> B<T> {
fn foo(_x: T::Item) where T: Trait {
COUNTER.fetch_add(10, SeqCst);
}
}
// Where-clause attached to free fn.
fn c<T>(_: T::Item) where T : Trait {
COUNTER.fetch_add(100, SeqCst);
}
// Where-clause attached to defaulted and non-defaulted trait method.
trait AnotherTrait {
fn method<T>(&self, _: T::Item) where T: Trait;
fn default_method<T>(&self, _: T::Item) where T: Trait {
COUNTER.fetch_add(1000, SeqCst);
}
}
struct D;
impl AnotherTrait for D {
fn method<T>(&self, _: T::Item) where T: Trait {
COUNTER.fetch_add(10000, SeqCst);
}
}
// Where-clause attached to trait and impl containing the method.
trait YetAnotherTrait<T>
where T : Trait
{
fn method(&self, _: T::Item);
fn default_method(&self, _: T::Item) {
COUNTER.fetch_add(100000, SeqCst);
}
}
struct E<T>(PhantomData<T>);
impl<T> YetAnotherTrait<T> for E<T>
where T : Trait
{
fn method(&self, _: T::Item) {
COUNTER.fetch_add(1000000, SeqCst);
}
}
// Where-clause attached to inherent impl containing the method.
struct F<T>(PhantomData<T>);
impl<T> F<T> where T : Trait {
fn method(&self, _: T::Item) {
COUNTER.fetch_add(10000000, SeqCst);
}
}
// Where-clause attached to struct.
#[allow(dead_code)]
struct G<T> where T : Trait {
data: T::Item,
phantom: PhantomData<T>,
}
fn main() {
A::foo::<Struct>(22);
B::<Struct>::foo(22);
c::<Struct>(22);
D.method::<Struct>(22);
D.default_method::<Struct>(22);
E(PhantomData::<Struct>).method(22);
E(PhantomData::<Struct>).default_method(22);
F(PhantomData::<Struct>).method(22);
G::<Struct> { data: 22, phantom: PhantomData };
assert_eq!(COUNTER.load(SeqCst), 11111111);
}