@@ -34,64 +34,135 @@ static STATIC_TUPLE: (AtomicUsize, String) = (ATOMIC, STRING);
34
34
#[ allow( clippy:: declare_interior_mutable_const) ]
35
35
const ONCE_INIT : Once = Once :: new ( ) ;
36
36
37
- struct Wrapper < T > ( T ) ;
38
-
39
- trait Trait < T : Trait2 < AssocType5 = AtomicUsize > > {
40
- type AssocType ;
41
- type AssocType2 ;
42
- type AssocType3 ;
43
-
37
+ // a constant whose type is a concrete type should be linted at the definition site.
38
+ trait ConcreteTypes {
44
39
const ATOMIC : AtomicUsize ; //~ ERROR interior mutable
45
40
const INTEGER : u64 ;
46
41
const STRING : String ;
47
- const SELF : Self ;
48
- const INPUT : T ;
49
- const INPUT_ASSOC : T :: AssocType4 ;
50
- const INPUT_ASSOC_2 : T :: AssocType5 ; //~ ERROR interior mutable
51
- const ASSOC : Self :: AssocType ;
52
- const ASSOC_2 : Self :: AssocType2 ;
53
- const WRAPPED_ASSOC_2 : Wrapper < Self :: AssocType2 > ;
54
- const WRAPPED_ASSOC_3 : Wrapper < Self :: AssocType3 > ;
55
-
56
- const AN_INPUT : T = Self :: INPUT ;
57
- declare_const ! ( ANOTHER_INPUT : T = Self :: INPUT ) ;
58
42
declare_const ! ( ANOTHER_ATOMIC : AtomicUsize = Self :: ATOMIC ) ; //~ ERROR interior mutable
59
43
}
60
44
61
- trait Trait2 {
62
- type AssocType4 ;
63
- type AssocType5 ;
45
+ impl ConcreteTypes for u64 {
46
+ const ATOMIC : AtomicUsize = AtomicUsize :: new ( 9 ) ;
47
+ const INTEGER : u64 = 10 ;
48
+ const STRING : String = String :: new ( ) ;
49
+ }
64
50
65
- const SELF_2 : Self ;
66
- const ASSOC_4 : Self :: AssocType4 ;
51
+ // a helper trait used below
52
+ trait ConstDefault {
53
+ const DEFAULT : Self ;
67
54
}
68
55
69
- impl < T : Trait2 < AssocType5 = AtomicUsize > > Trait < T > for u64 {
70
- type AssocType = u16 ;
71
- type AssocType2 = AtomicUsize ;
72
- type AssocType3 = T ;
56
+ // a constant whose type is a generic type should be linted at the implementation site.
57
+ trait GenericTypes < T , U > {
58
+ const TO_REMAIN_GENERIC : T ;
59
+ const TO_BE_CONCRETE : U ;
73
60
74
- const ATOMIC : AtomicUsize = AtomicUsize :: new ( 9 ) ;
75
- const INTEGER : u64 = 10 ;
76
- const STRING : String = String :: new ( ) ;
77
- const SELF : Self = 11 ;
78
- const INPUT : T = T :: SELF_2 ;
79
- const INPUT_ASSOC : T :: AssocType4 = T :: ASSOC_4 ;
80
- const INPUT_ASSOC_2 : T :: AssocType5 = AtomicUsize :: new ( 16 ) ;
81
- const ASSOC : Self :: AssocType = 13 ;
82
- const ASSOC_2 : Self :: AssocType2 = AtomicUsize :: new ( 15 ) ; //~ ERROR interior mutable
83
- const WRAPPED_ASSOC_2 : Wrapper < Self :: AssocType2 > = Wrapper ( AtomicUsize :: new ( 16 ) ) ; //~ ERROR interior mutable
84
- const WRAPPED_ASSOC_3 : Wrapper < Self :: AssocType3 > = Wrapper ( T :: SELF_2 ) ;
61
+ const HAVING_DEFAULT : T = Self :: TO_REMAIN_GENERIC ;
62
+ declare_const ! ( IN_MACRO : T = Self :: TO_REMAIN_GENERIC ) ;
63
+ }
64
+
65
+ impl < T : ConstDefault > GenericTypes < T , AtomicUsize > for u64 {
66
+ const TO_REMAIN_GENERIC : T = T :: DEFAULT ;
67
+ const TO_BE_CONCRETE : AtomicUsize = AtomicUsize :: new ( 11 ) ; //~ ERROR interior mutable
68
+ }
69
+
70
+ // a helper type used below
71
+ struct Wrapper < T > ( T ) ;
72
+
73
+ // a constant whose type is an associated type should be linted at the implementation site, too.
74
+ trait AssocTypes {
75
+ type ToBeFrozen ;
76
+ type ToBeUnfrozen ;
77
+ type ToBeGenericParam ;
78
+
79
+ const TO_BE_FROZEN : Self :: ToBeFrozen ;
80
+ const TO_BE_UNFROZEN : Self :: ToBeUnfrozen ;
81
+ const WRAPPED_TO_BE_UNFROZEN : Wrapper < Self :: ToBeUnfrozen > ;
82
+ // to ensure it can handle things when a generic type remains after normalization.
83
+ const WRAPPED_TO_BE_GENERIC_PARAM : Wrapper < Self :: ToBeGenericParam > ;
84
+ }
85
+
86
+ impl < T : ConstDefault > AssocTypes for Vec < T > {
87
+ type ToBeFrozen = u16 ;
88
+ type ToBeUnfrozen = AtomicUsize ;
89
+ type ToBeGenericParam = T ;
90
+
91
+ const TO_BE_FROZEN : Self :: ToBeFrozen = 12 ;
92
+ const TO_BE_UNFROZEN : Self :: ToBeUnfrozen = AtomicUsize :: new ( 13 ) ; //~ ERROR interior mutable
93
+ const WRAPPED_TO_BE_UNFROZEN : Wrapper < Self :: ToBeUnfrozen > = Wrapper ( AtomicUsize :: new ( 14 ) ) ; //~ ERROR interior mutable
94
+ const WRAPPED_TO_BE_GENERIC_PARAM : Wrapper < Self :: ToBeGenericParam > = Wrapper ( T :: DEFAULT ) ;
85
95
}
86
96
87
- struct Local < T , U > ( T , U ) ;
97
+ // a helper trait used below
98
+ trait AssocTypesHelper {
99
+ type NotToBeBounded ;
100
+ type ToBeBounded ;
88
101
89
- impl < T : Trait < U > , U : Trait2 < AssocType5 = AtomicUsize > > Local < T , U > {
90
- const ASSOC_5 : AtomicUsize = AtomicUsize :: new ( 14 ) ; //~ ERROR interior mutable
102
+ const NOT_TO_BE_BOUNDED : Self :: NotToBeBounded ;
103
+ }
104
+
105
+ // a constant whose type is an assoc type originated from a generic param bounded at the definition
106
+ // site should be linted at there.
107
+ trait AssocTypesFromGenericParam < T >
108
+ where
109
+ T : AssocTypesHelper < ToBeBounded = AtomicUsize > ,
110
+ {
111
+ const NOT_BOUNDED : T :: NotToBeBounded ;
112
+ const BOUNDED : T :: ToBeBounded ; //~ ERROR interior mutable
113
+ }
114
+
115
+ impl < T > AssocTypesFromGenericParam < T > for u64
116
+ where
117
+ T : AssocTypesHelper < ToBeBounded = AtomicUsize > ,
118
+ {
119
+ // an associated type could remain unknown in a trait impl.
120
+ const NOT_BOUNDED : T :: NotToBeBounded = T :: NOT_TO_BE_BOUNDED ;
121
+ const BOUNDED : T :: ToBeBounded = AtomicUsize :: new ( 15 ) ;
122
+ }
123
+
124
+ trait SelfType {
125
+ const SELF : Self ;
126
+ }
127
+
128
+ impl SelfType for u64 {
129
+ const SELF : Self = 16 ;
130
+ }
131
+
132
+ impl SelfType for AtomicUsize {
133
+ // this (interior mutable `Self` const) exists in `parking_lot`.
134
+ // `const_trait_impl` will replace it in the future, hopefully.
135
+ const SELF : Self = AtomicUsize :: new ( 17 ) ; //~ ERROR interior mutable
136
+ }
137
+
138
+ // Even though a constant contains a generic type, if it also have a interior mutable type,
139
+ // it should be linted at the definition site.
140
+ trait BothOfCellAndGeneric < T > {
141
+ // this is a false negative in the current implementation.
142
+ const DIRECT : Cell < T > ;
143
+ const INDIRECT : Cell < * const T > ; //~ ERROR interior mutable
144
+ }
145
+
146
+ impl < T : ConstDefault > BothOfCellAndGeneric < T > for u64 {
147
+ const DIRECT : Cell < T > = Cell :: new ( T :: DEFAULT ) ;
148
+ const INDIRECT : Cell < * const T > = Cell :: new ( std:: ptr:: null ( ) ) ;
149
+ }
150
+
151
+ struct Local < T > ( T ) ;
152
+
153
+ // a constant in an inherent impl are essentially the same as a normal const item
154
+ // except there can be a generic or associated type.
155
+ impl < T > Local < T >
156
+ where
157
+ T : ConstDefault + AssocTypesHelper < ToBeBounded = AtomicUsize > ,
158
+ {
159
+ const ATOMIC : AtomicUsize = AtomicUsize :: new ( 18 ) ; //~ ERROR interior mutable
91
160
const COW : Cow < ' static , str > = Cow :: Borrowed ( "tuvwxy" ) ;
92
- const U_SELF : U = U :: SELF_2 ;
93
- const T_ASSOC : T :: AssocType = T :: ASSOC ;
94
- const U_ASSOC : U :: AssocType5 = AtomicUsize :: new ( 17 ) ; //~ ERROR interior mutable
161
+
162
+ const GENERIC_TYPE : T = T :: DEFAULT ;
163
+
164
+ const ASSOC_TYPE : T :: NotToBeBounded = T :: NOT_TO_BE_BOUNDED ;
165
+ const BOUNDED_ASSOC_TYPE : T :: ToBeBounded = AtomicUsize :: new ( 19 ) ; //~ ERROR interior mutable
95
166
}
96
167
97
168
fn main ( ) { }
0 commit comments