1
- //! Debugging code to test fingerprints computed for query results.
2
- //! For each node marked with `#[rustc_clean]` or `#[rustc_dirty]`,
3
- //! we will compare the fingerprint from the current and from the previous
1
+ //! Debugging code to test fingerprints computed for query results. For each node marked with
2
+ //! `#[rustc_clean]` we will compare the fingerprint from the current and from the previous
4
3
//! compilation session as appropriate:
5
4
//!
6
5
//! - `#[rustc_clean(cfg="rev2", except="typeck")]` if we are
@@ -30,7 +29,6 @@ use std::iter::FromIterator;
30
29
use std:: vec:: Vec ;
31
30
32
31
const EXCEPT : Symbol = sym:: except;
33
- const LABEL : Symbol = sym:: label;
34
32
const CFG : Symbol = sym:: cfg;
35
33
36
34
// Base and Extra labels to build up the labels
@@ -101,6 +99,12 @@ const LABELS_FN_IN_TRAIT: &[&[&str]] =
101
99
/// For generic cases like inline-assembly, modules, etc.
102
100
const LABELS_HIR_ONLY : & [ & [ & str ] ] = & [ BASE_HIR ] ;
103
101
102
+ /// Impl `DepNode`s.
103
+ const LABELS_TRAIT : & [ & [ & str ] ] = & [
104
+ BASE_HIR ,
105
+ & [ label_strs:: associated_item_def_ids, label_strs:: predicates_of, label_strs:: generics_of] ,
106
+ ] ;
107
+
104
108
/// Impl `DepNode`s.
105
109
const LABELS_IMPL : & [ & [ & str ] ] = & [ BASE_HIR , BASE_IMPL ] ;
106
110
@@ -122,22 +126,12 @@ struct Assertion {
122
126
dirty : Labels ,
123
127
}
124
128
125
- impl Assertion {
126
- fn from_clean_labels ( labels : Labels ) -> Assertion {
127
- Assertion { clean : labels, dirty : Labels :: default ( ) }
128
- }
129
-
130
- fn from_dirty_labels ( labels : Labels ) -> Assertion {
131
- Assertion { clean : Labels :: default ( ) , dirty : labels }
132
- }
133
- }
134
-
135
129
pub fn check_dirty_clean_annotations ( tcx : TyCtxt < ' _ > ) {
136
130
if !tcx. sess . opts . debugging_opts . query_dep_graph {
137
131
return ;
138
132
}
139
133
140
- // can't add `#[rustc_dirty ]` etc without opting in to this feature
134
+ // can't add `#[rustc_clean ]` etc without opting in to this feature
141
135
if !tcx. features ( ) . rustc_attrs {
142
136
return ;
143
137
}
@@ -147,11 +141,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
147
141
let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs : Default :: default ( ) } ;
148
142
krate. visit_all_item_likes ( & mut dirty_clean_visitor) ;
149
143
150
- let mut all_attrs = FindAllAttrs {
151
- tcx,
152
- attr_names : & [ sym:: rustc_dirty, sym:: rustc_clean] ,
153
- found_attrs : vec ! [ ] ,
154
- } ;
144
+ let mut all_attrs = FindAllAttrs { tcx, found_attrs : vec ! [ ] } ;
155
145
intravisit:: walk_crate ( & mut all_attrs, krate) ;
156
146
157
147
// Note that we cannot use the existing "unused attribute"-infrastructure
@@ -169,37 +159,20 @@ pub struct DirtyCleanVisitor<'tcx> {
169
159
impl DirtyCleanVisitor < ' tcx > {
170
160
/// Possibly "deserialize" the attribute into a clean/dirty assertion
171
161
fn assertion_maybe ( & mut self , item_id : LocalDefId , attr : & Attribute ) -> Option < Assertion > {
172
- let is_clean = if self . tcx . sess . check_name ( attr, sym:: rustc_dirty) {
173
- false
174
- } else if self . tcx . sess . check_name ( attr, sym:: rustc_clean) {
175
- true
176
- } else {
162
+ if !self . tcx . sess . check_name ( attr, sym:: rustc_clean) {
177
163
// skip: not rustc_clean/dirty
178
164
return None ;
179
- } ;
165
+ }
180
166
if !check_config ( self . tcx , attr) {
181
167
// skip: not the correct `cfg=`
182
168
return None ;
183
169
}
184
- let assertion = if let Some ( labels) = self . labels ( attr) {
185
- if is_clean {
186
- Assertion :: from_clean_labels ( labels)
187
- } else {
188
- Assertion :: from_dirty_labels ( labels)
189
- }
190
- } else {
191
- self . assertion_auto ( item_id, attr, is_clean)
192
- } ;
170
+ let assertion = self . assertion_auto ( item_id, attr) ;
193
171
Some ( assertion)
194
172
}
195
173
196
174
/// Gets the "auto" assertion on pre-validated attr, along with the `except` labels.
197
- fn assertion_auto (
198
- & mut self ,
199
- item_id : LocalDefId ,
200
- attr : & Attribute ,
201
- is_clean : bool ,
202
- ) -> Assertion {
175
+ fn assertion_auto ( & mut self , item_id : LocalDefId , attr : & Attribute ) -> Assertion {
203
176
let ( name, mut auto) = self . auto_labels ( item_id, attr) ;
204
177
let except = self . except ( attr) ;
205
178
for e in except. iter ( ) {
@@ -211,21 +184,7 @@ impl DirtyCleanVisitor<'tcx> {
211
184
self . tcx . sess . span_fatal ( attr. span , & msg) ;
212
185
}
213
186
}
214
- if is_clean {
215
- Assertion { clean : auto, dirty : except }
216
- } else {
217
- Assertion { clean : except, dirty : auto }
218
- }
219
- }
220
-
221
- fn labels ( & self , attr : & Attribute ) -> Option < Labels > {
222
- for item in attr. meta_item_list ( ) . unwrap_or_else ( Vec :: new) {
223
- if item. has_name ( LABEL ) {
224
- let value = expect_associated_value ( self . tcx , & item) ;
225
- return Some ( self . resolve_labels ( & item, value) ) ;
226
- }
227
- }
228
- None
187
+ Assertion { clean : auto, dirty : except }
229
188
}
230
189
231
190
/// `except=` attribute value
@@ -288,20 +247,7 @@ impl DirtyCleanVisitor<'tcx> {
288
247
HirItem :: Union ( ..) => ( "ItemUnion" , LABELS_ADT ) ,
289
248
290
249
// Represents a Trait Declaration
291
- // FIXME(michaelwoerister): trait declaration is buggy because sometimes some of
292
- // the depnodes don't exist (because they legitimately didn't need to be
293
- // calculated)
294
- //
295
- // michaelwoerister and vitiral came up with a possible solution,
296
- // to just do this before every query
297
- // ```
298
- // ::rustc_middle::ty::query::plumbing::force_from_dep_node(tcx, dep_node)
299
- // ```
300
- //
301
- // However, this did not seem to work effectively and more bugs were hit.
302
- // Nebie @vitiral gave up :)
303
- //
304
- //HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT),
250
+ HirItem :: Trait ( ..) => ( "ItemTrait" , LABELS_TRAIT ) ,
305
251
306
252
// An implementation, eg `impl<A> Trait for Foo { .. }`
307
253
HirItem :: Impl { .. } => ( "ItemKind::Impl" , LABELS_IMPL ) ,
@@ -434,35 +380,23 @@ impl ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
434
380
}
435
381
}
436
382
437
- /// Given a `#[rustc_dirty]` or `#[rustc_clean]` attribute, scan
438
- /// for a `cfg="foo"` attribute and check whether we have a cfg
439
- /// flag called `foo`.
440
- ///
441
- /// Also make sure that the `label` and `except` fields do not
442
- /// both exist.
383
+ /// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have
384
+ /// a cfg flag called `foo`.
443
385
fn check_config ( tcx : TyCtxt < ' _ > , attr : & Attribute ) -> bool {
444
386
debug ! ( "check_config(attr={:?})" , attr) ;
445
387
let config = & tcx. sess . parse_sess . config ;
446
388
debug ! ( "check_config: config={:?}" , config) ;
447
- let ( mut cfg, mut except , mut label ) = ( None , false , false ) ;
389
+ let mut cfg = None ;
448
390
for item in attr. meta_item_list ( ) . unwrap_or_else ( Vec :: new) {
449
391
if item. has_name ( CFG ) {
450
392
let value = expect_associated_value ( tcx, & item) ;
451
393
debug ! ( "check_config: searching for cfg {:?}" , value) ;
452
394
cfg = Some ( config. contains ( & ( value, None ) ) ) ;
453
- }
454
- if item. has_name ( LABEL ) {
455
- label = true ;
456
- }
457
- if item. has_name ( EXCEPT ) {
458
- except = true ;
395
+ } else if !item. has_name ( EXCEPT ) {
396
+ tcx. sess . span_err ( attr. span , & format ! ( "unknown item `{}`" , item. name_or_empty( ) ) ) ;
459
397
}
460
398
}
461
399
462
- if label && except {
463
- tcx. sess . span_fatal ( attr. span , "must specify only one of: `label`, `except`" ) ;
464
- }
465
-
466
400
match cfg {
467
401
None => tcx. sess . span_fatal ( attr. span , "no cfg attribute" ) ,
468
402
Some ( c) => c,
@@ -483,21 +417,18 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
483
417
}
484
418
}
485
419
486
- // A visitor that collects all #[rustc_dirty]/#[ rustc_clean] attributes from
420
+ // A visitor that collects all #[rustc_clean] attributes from
487
421
// the HIR. It is used to verify that we really ran checks for all annotated
488
422
// nodes.
489
- pub struct FindAllAttrs < ' a , ' tcx > {
423
+ pub struct FindAllAttrs < ' tcx > {
490
424
tcx : TyCtxt < ' tcx > ,
491
- attr_names : & ' a [ Symbol ] ,
492
425
found_attrs : Vec < & ' tcx Attribute > ,
493
426
}
494
427
495
- impl FindAllAttrs < ' _ , ' tcx > {
428
+ impl FindAllAttrs < ' tcx > {
496
429
fn is_active_attr ( & mut self , attr : & Attribute ) -> bool {
497
- for attr_name in self . attr_names {
498
- if self . tcx . sess . check_name ( attr, * attr_name) && check_config ( self . tcx , attr) {
499
- return true ;
500
- }
430
+ if self . tcx . sess . check_name ( attr, sym:: rustc_clean) && check_config ( self . tcx , attr) {
431
+ return true ;
501
432
}
502
433
503
434
false
@@ -506,17 +437,14 @@ impl FindAllAttrs<'_, 'tcx> {
506
437
fn report_unchecked_attrs ( & self , mut checked_attrs : FxHashSet < ast:: AttrId > ) {
507
438
for attr in & self . found_attrs {
508
439
if !checked_attrs. contains ( & attr. id ) {
509
- self . tcx . sess . span_err (
510
- attr. span ,
511
- "found unchecked `#[rustc_dirty]` / `#[rustc_clean]` attribute" ,
512
- ) ;
440
+ self . tcx . sess . span_err ( attr. span , "found unchecked `#[rustc_clean]` attribute" ) ;
513
441
checked_attrs. insert ( attr. id ) ;
514
442
}
515
443
}
516
444
}
517
445
}
518
446
519
- impl intravisit:: Visitor < ' tcx > for FindAllAttrs < ' _ , ' tcx > {
447
+ impl intravisit:: Visitor < ' tcx > for FindAllAttrs < ' tcx > {
520
448
type Map = Map < ' tcx > ;
521
449
522
450
fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
0 commit comments