1
1
//! Determining which types for which we can emit `#[derive(Debug)]`.
2
- use super :: analysis:: MonotoneFramework ;
3
- use ir:: context:: { BindgenContext , ItemId } ;
4
- use ir:: item:: ItemSet ;
2
+
3
+ use super :: { ConstrainResult , MonotoneFramework } ;
5
4
use std:: collections:: HashSet ;
6
5
use std:: collections:: HashMap ;
6
+ use ir:: context:: { BindgenContext , ItemId } ;
7
7
use ir:: traversal:: EdgeKind ;
8
8
use ir:: ty:: RUST_DERIVE_IN_ARRAY_LIMIT ;
9
9
use ir:: ty:: TypeKind ;
@@ -16,7 +16,7 @@ use ir::comp::CompKind;
16
16
17
17
/// An analysis that finds for each IR item whether debug cannot be derived.
18
18
///
19
- /// We use the monotone constraint function `cant_derive_debug `, defined as
19
+ /// We use the monotone constraint function `cannot_derive_debug `, defined as
20
20
/// follows:
21
21
///
22
22
/// * If T is Opaque and layout of the type is known, get this layout as opaque
@@ -34,17 +34,17 @@ use ir::comp::CompKind;
34
34
/// derived debug if any of the template arguments or template definition
35
35
/// cannot derive debug.
36
36
#[ derive( Debug , Clone ) ]
37
- pub struct CantDeriveDebugAnalysis < ' ctx , ' gen >
37
+ pub struct CannotDeriveDebug < ' ctx , ' gen >
38
38
where ' gen : ' ctx
39
39
{
40
40
ctx : & ' ctx BindgenContext < ' gen > ,
41
41
42
42
// The incremental result of this analysis's computation. Everything in this
43
43
// set cannot derive debug.
44
- cant_derive_debug : HashSet < ItemId > ,
44
+ cannot_derive_debug : HashSet < ItemId > ,
45
45
46
46
// Dependencies saying that if a key ItemId has been inserted into the
47
- // `cant_derive_debug ` set, then each of the ids in Vec<ItemId> need to be
47
+ // `cannot_derive_debug ` set, then each of the ids in Vec<ItemId> need to be
48
48
// considered again.
49
49
//
50
50
// This is a subset of the natural IR graph with reversed edges, where we
@@ -53,7 +53,7 @@ pub struct CantDeriveDebugAnalysis<'ctx, 'gen>
53
53
dependencies : HashMap < ItemId , Vec < ItemId > > ,
54
54
}
55
55
56
- impl < ' ctx , ' gen > CantDeriveDebugAnalysis < ' ctx , ' gen > {
56
+ impl < ' ctx , ' gen > CannotDeriveDebug < ' ctx , ' gen > {
57
57
fn consider_edge ( kind : EdgeKind ) -> bool {
58
58
match kind {
59
59
// These are the only edges that can affect whether a type can derive
@@ -77,79 +77,69 @@ impl<'ctx, 'gen> CantDeriveDebugAnalysis<'ctx, 'gen> {
77
77
}
78
78
}
79
79
80
- fn insert ( & mut self , id : ItemId ) -> bool {
81
- let was_already_in = self . cant_derive_debug . insert ( id) ;
80
+ fn insert ( & mut self , id : ItemId ) -> ConstrainResult {
81
+ let was_not_already_in_set = self . cannot_derive_debug . insert ( id) ;
82
82
assert ! (
83
- was_already_in,
84
- format!( "We shouldn't try and insert twice because if it was already in the set, \
85
- `constrain` would have exited early.: {:?}", id)
83
+ was_not_already_in_set,
84
+ "We shouldn't try and insert {:?} twice because if it was \
85
+ already in the set, `constrain` should have exited early.",
86
+ id
86
87
) ;
87
- true
88
+ ConstrainResult :: Changed
88
89
}
89
90
}
90
91
91
- impl < ' ctx , ' gen > MonotoneFramework for CantDeriveDebugAnalysis < ' ctx , ' gen > {
92
+ impl < ' ctx , ' gen > MonotoneFramework for CannotDeriveDebug < ' ctx , ' gen > {
92
93
type Node = ItemId ;
93
94
type Extra = & ' ctx BindgenContext < ' gen > ;
94
95
type Output = HashSet < ItemId > ;
95
96
96
- fn new ( ctx : & ' ctx BindgenContext < ' gen > ) -> CantDeriveDebugAnalysis < ' ctx , ' gen > {
97
- let cant_derive_debug = HashSet :: new ( ) ;
97
+ fn new ( ctx : & ' ctx BindgenContext < ' gen > ) -> CannotDeriveDebug < ' ctx , ' gen > {
98
+ let cannot_derive_debug = HashSet :: new ( ) ;
98
99
let mut dependencies = HashMap :: new ( ) ;
99
- let whitelisted_items: HashSet < _ > = ctx. whitelisted_items ( ) . collect ( ) ;
100
-
101
- let whitelisted_and_blacklisted_items: ItemSet = whitelisted_items. iter ( )
102
- . cloned ( )
103
- . flat_map ( |i| {
104
- let mut reachable = vec ! [ i] ;
105
- i. trace ( ctx, & mut |s, _| {
106
- reachable. push ( s) ;
107
- } , & ( ) ) ;
108
- reachable
109
- } )
110
- . collect ( ) ;
111
100
112
- for item in whitelisted_and_blacklisted_items {
101
+ for & item in ctx . whitelisted_items ( ) {
113
102
dependencies. entry ( item) . or_insert ( vec ! [ ] ) ;
114
103
115
104
{
116
105
// We reverse our natural IR graph edges to find dependencies
117
106
// between nodes.
118
107
item. trace ( ctx, & mut |sub_item : ItemId , edge_kind| {
119
- if Self :: consider_edge ( edge_kind) {
120
- dependencies. entry ( sub_item)
121
- . or_insert ( vec ! [ ] )
122
- . push ( item) ;
108
+ if ctx. whitelisted_items ( ) . contains ( & sub_item) &&
109
+ Self :: consider_edge ( edge_kind) {
110
+ dependencies. entry ( sub_item)
111
+ . or_insert ( vec ! [ ] )
112
+ . push ( item) ;
123
113
}
124
114
} , & ( ) ) ;
125
115
}
126
116
}
127
117
128
- CantDeriveDebugAnalysis {
129
- ctx : ctx ,
130
- cant_derive_debug : cant_derive_debug ,
131
- dependencies : dependencies ,
118
+ CannotDeriveDebug {
119
+ ctx,
120
+ cannot_derive_debug ,
121
+ dependencies,
132
122
}
133
123
}
134
124
135
125
fn initial_worklist ( & self ) -> Vec < ItemId > {
136
- self . ctx . whitelisted_items ( ) . collect ( )
126
+ self . ctx . whitelisted_items ( ) . iter ( ) . cloned ( ) . collect ( )
137
127
}
138
128
139
- fn constrain ( & mut self , id : ItemId ) -> bool {
140
- if self . cant_derive_debug . contains ( & id) {
141
- return false ;
129
+ fn constrain ( & mut self , id : ItemId ) -> ConstrainResult {
130
+ if self . cannot_derive_debug . contains ( & id) {
131
+ return ConstrainResult :: Same ;
142
132
}
143
133
144
134
let item = self . ctx . resolve_item ( id) ;
145
135
let ty = match item. as_type ( ) {
146
- None => return false ,
136
+ None => return ConstrainResult :: Same ,
147
137
Some ( ty) => ty
148
138
} ;
149
139
150
140
match * ty. kind ( ) {
151
- // handle the simple case
152
- // These can derive debug without further information
141
+ // Handle the simple cases. These can derive debug without further
142
+ // information.
153
143
TypeKind :: Void |
154
144
TypeKind :: NullPtr |
155
145
TypeKind :: Int ( ..) |
@@ -164,97 +154,113 @@ impl<'ctx, 'gen> MonotoneFramework for CantDeriveDebugAnalysis<'ctx, 'gen> {
164
154
TypeKind :: ObjCInterface ( ..) |
165
155
TypeKind :: ObjCId |
166
156
TypeKind :: ObjCSel => {
167
- return false ;
157
+ ConstrainResult :: Same
168
158
} ,
159
+
169
160
TypeKind :: Opaque => {
170
161
if ty. layout ( self . ctx )
171
162
. map_or ( true , |l| l. opaque ( ) . can_trivially_derive_debug ( self . ctx , ( ) ) ) {
172
- return false ;
163
+ ConstrainResult :: Same
173
164
} else {
174
- return self . insert ( id) ;
165
+ self . insert ( id)
175
166
}
176
167
} ,
168
+
177
169
TypeKind :: Array ( t, len) => {
170
+ if self . cannot_derive_debug . contains ( & t) {
171
+ return self . insert ( id) ;
172
+ }
173
+
178
174
if len <= RUST_DERIVE_IN_ARRAY_LIMIT {
179
- if self . cant_derive_debug . contains ( & t) {
180
- return self . insert ( id) ;
181
- }
182
- return false ;
175
+ ConstrainResult :: Same
183
176
} else {
184
- return self . insert ( id) ;
177
+ self . insert ( id)
185
178
}
186
179
} ,
180
+
187
181
TypeKind :: ResolvedTypeRef ( t) |
188
182
TypeKind :: TemplateAlias ( t, _) |
189
183
TypeKind :: Alias ( t) => {
190
- if self . cant_derive_debug . contains ( & t) {
191
- return self . insert ( id) ;
184
+ if self . cannot_derive_debug . contains ( & t) {
185
+ self . insert ( id)
186
+ } else {
187
+ ConstrainResult :: Same
192
188
}
193
- return false ;
194
189
} ,
190
+
195
191
TypeKind :: Comp ( ref info) => {
196
192
if info. has_non_type_template_params ( ) {
197
- if ty. layout ( self . ctx ) . map_or ( true ,
198
- |l| l. opaque ( ) . can_trivially_derive_debug ( self . ctx , ( ) ) ) {
199
- return false ;
193
+ if ty. layout ( self . ctx )
194
+ . map_or ( true ,
195
+ |l| l. opaque ( ) . can_trivially_derive_debug ( self . ctx , ( ) ) ) {
196
+ return ConstrainResult :: Same ;
200
197
} else {
201
198
return self . insert ( id) ;
202
199
}
203
200
}
201
+
204
202
if info. kind ( ) == CompKind :: Union {
205
203
if self . ctx . options ( ) . unstable_rust {
206
204
return self . insert ( id) ;
207
205
}
208
206
209
- if ty. layout ( self . ctx ) . map_or ( true ,
210
- |l| l. opaque ( ) . can_trivially_derive_debug ( self . ctx , ( ) ) ) {
211
- return false ;
207
+ if ty. layout ( self . ctx )
208
+ . map_or ( true ,
209
+ |l| l. opaque ( ) . can_trivially_derive_debug ( self . ctx , ( ) ) ) {
210
+ return ConstrainResult :: Same ;
212
211
} else {
213
212
return self . insert ( id) ;
214
213
}
215
214
}
216
- let bases_cant_derive = info. base_members ( )
215
+
216
+ let bases_cannot_derive = info. base_members ( )
217
217
. iter ( )
218
- . any ( |base| self . cant_derive_debug . contains ( & base. ty ) ) ;
219
- if bases_cant_derive {
218
+ . any ( |base| self . cannot_derive_debug . contains ( & base. ty ) ) ;
219
+ if bases_cannot_derive {
220
220
return self . insert ( id) ;
221
221
}
222
- let fields_cant_derive = info. fields ( )
222
+
223
+ let fields_cannot_derive = info. fields ( )
223
224
. iter ( )
224
225
. any ( |f| {
225
- match f {
226
- & Field :: DataMember ( ref data) => self . cant_derive_debug . contains ( & data. ty ( ) ) ,
227
- & Field :: Bitfields ( ref bfu) => bfu. bitfields ( )
228
- . iter ( ) . any ( |b| {
229
- self . cant_derive_debug . contains ( & b. ty ( ) )
230
- } )
226
+ match * f {
227
+ Field :: DataMember ( ref data) => {
228
+ self . cannot_derive_debug . contains ( & data. ty ( ) )
229
+ }
230
+ Field :: Bitfields ( ref bfu) => {
231
+ bfu. bitfields ( )
232
+ . iter ( ) . any ( |b| {
233
+ self . cannot_derive_debug . contains ( & b. ty ( ) )
234
+ } )
235
+ }
231
236
}
232
237
} ) ;
233
- if fields_cant_derive {
238
+ if fields_cannot_derive {
234
239
return self . insert ( id) ;
235
240
}
236
- false
241
+
242
+ ConstrainResult :: Same
237
243
} ,
244
+
238
245
TypeKind :: Pointer ( inner) => {
239
- let inner_type = self . ctx . resolve_type ( inner) ;
240
- if let TypeKind :: Function ( ref sig) =
241
- * inner_type. canonical_type ( self . ctx ) . kind ( ) {
242
- if sig. can_trivially_derive_debug ( & self . ctx , ( ) ) {
243
- return false ;
244
- } else {
245
- return self . insert ( id) ;
246
- }
246
+ let inner_type = self . ctx . resolve_type ( inner) . canonical_type ( self . ctx ) ;
247
+ if let TypeKind :: Function ( ref sig) = * inner_type. kind ( ) {
248
+ if !sig. can_trivially_derive_debug ( & self . ctx , ( ) ) {
249
+ return self . insert ( id) ;
247
250
}
248
- false
251
+ }
252
+ ConstrainResult :: Same
249
253
} ,
254
+
250
255
TypeKind :: TemplateInstantiation ( ref template) => {
251
- let args_cant_derive = template. template_arguments ( )
256
+ let args_cannot_derive = template. template_arguments ( )
252
257
. iter ( )
253
- . any ( |arg| self . cant_derive_debug . contains ( & arg) ) ;
254
- if args_cant_derive {
258
+ . any ( |arg| self . cannot_derive_debug . contains ( & arg) ) ;
259
+ if args_cannot_derive {
255
260
return self . insert ( id) ;
256
261
}
257
- let ty_cant_derive = template. template_definition ( )
262
+
263
+ let ty_cannot_derive = template. template_definition ( )
258
264
. into_resolver ( )
259
265
. through_type_refs ( )
260
266
. through_type_aliases ( )
@@ -268,19 +274,26 @@ impl<'ctx, 'gen> MonotoneFramework for CantDeriveDebugAnalysis<'ctx, 'gen> {
268
274
// idea of the layout than the definition does.
269
275
if c. has_non_type_template_params ( ) {
270
276
let opaque = ty. layout ( self . ctx )
271
- . or_else ( || self . ctx . resolve_type ( template. template_definition ( ) ) . layout ( self . ctx ) )
277
+ . or_else ( || {
278
+ self . ctx
279
+ . resolve_type ( template. template_definition ( ) )
280
+ . layout ( self . ctx )
281
+ } )
272
282
. unwrap_or ( Layout :: zero ( ) )
273
283
. opaque ( ) ;
274
284
Some ( !opaque. can_trivially_derive_debug ( & self . ctx , ( ) ) )
275
285
} else {
276
286
None
277
287
}
278
288
} )
279
- . unwrap_or_else ( || self . cant_derive_debug . contains ( & template. template_definition ( ) ) ) ;
280
- if ty_cant_derive {
289
+ . unwrap_or_else ( || {
290
+ self . cannot_derive_debug . contains ( & template. template_definition ( ) )
291
+ } ) ;
292
+ if ty_cannot_derive {
281
293
return self . insert ( id) ;
282
294
}
283
- false
295
+
296
+ ConstrainResult :: Same
284
297
} ,
285
298
}
286
299
}
@@ -297,8 +310,8 @@ impl<'ctx, 'gen> MonotoneFramework for CantDeriveDebugAnalysis<'ctx, 'gen> {
297
310
}
298
311
}
299
312
300
- impl < ' ctx , ' gen > From < CantDeriveDebugAnalysis < ' ctx , ' gen > > for HashSet < ItemId > {
301
- fn from ( analysis : CantDeriveDebugAnalysis < ' ctx , ' gen > ) -> Self {
302
- analysis. cant_derive_debug
313
+ impl < ' ctx , ' gen > From < CannotDeriveDebug < ' ctx , ' gen > > for HashSet < ItemId > {
314
+ fn from ( analysis : CannotDeriveDebug < ' ctx , ' gen > ) -> Self {
315
+ analysis. cannot_derive_debug
303
316
}
304
317
}
0 commit comments