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
43//! compilation session as appropriate:
54//!
65//! - `#[rustc_clean(cfg="rev2", except="typeck")]` if we are
@@ -30,7 +29,6 @@ use std::iter::FromIterator;
3029use std:: vec:: Vec ;
3130
3231const EXCEPT : Symbol = sym:: except;
33- const LABEL : Symbol = sym:: label;
3432const CFG : Symbol = sym:: cfg;
3533
3634// Base and Extra labels to build up the labels
@@ -101,6 +99,12 @@ const LABELS_FN_IN_TRAIT: &[&[&str]] =
10199/// For generic cases like inline-assembly, modules, etc.
102100const LABELS_HIR_ONLY : & [ & [ & str ] ] = & [ BASE_HIR ] ;
103101
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+
104108/// Impl `DepNode`s.
105109const LABELS_IMPL : & [ & [ & str ] ] = & [ BASE_HIR , BASE_IMPL ] ;
106110
@@ -122,22 +126,12 @@ struct Assertion {
122126 dirty : Labels ,
123127}
124128
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-
135129pub fn check_dirty_clean_annotations ( tcx : TyCtxt < ' _ > ) {
136130 if !tcx. sess . opts . debugging_opts . query_dep_graph {
137131 return ;
138132 }
139133
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
141135 if !tcx. features ( ) . rustc_attrs {
142136 return ;
143137 }
@@ -147,11 +141,7 @@ pub fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
147141 let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs : Default :: default ( ) } ;
148142 krate. visit_all_item_likes ( & mut dirty_clean_visitor) ;
149143
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 ! [ ] } ;
155145 intravisit:: walk_crate ( & mut all_attrs, krate) ;
156146
157147 // Note that we cannot use the existing "unused attribute"-infrastructure
@@ -169,37 +159,20 @@ pub struct DirtyCleanVisitor<'tcx> {
169159impl DirtyCleanVisitor < ' tcx > {
170160 /// Possibly "deserialize" the attribute into a clean/dirty assertion
171161 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) {
177163 // skip: not rustc_clean/dirty
178164 return None ;
179- } ;
165+ }
180166 if !check_config ( self . tcx , attr) {
181167 // skip: not the correct `cfg=`
182168 return None ;
183169 }
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) ;
193171 Some ( assertion)
194172 }
195173
196174 /// 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 {
203176 let ( name, mut auto) = self . auto_labels ( item_id, attr) ;
204177 let except = self . except ( attr) ;
205178 for e in except. iter ( ) {
@@ -211,21 +184,7 @@ impl DirtyCleanVisitor<'tcx> {
211184 self . tcx . sess . span_fatal ( attr. span , & msg) ;
212185 }
213186 }
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 }
229188 }
230189
231190 /// `except=` attribute value
@@ -288,20 +247,7 @@ impl DirtyCleanVisitor<'tcx> {
288247 HirItem :: Union ( ..) => ( "ItemUnion" , LABELS_ADT ) ,
289248
290249 // 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 ) ,
305251
306252 // An implementation, eg `impl<A> Trait for Foo { .. }`
307253 HirItem :: Impl { .. } => ( "ItemKind::Impl" , LABELS_IMPL ) ,
@@ -434,35 +380,23 @@ impl ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'tcx> {
434380 }
435381}
436382
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`.
443385fn check_config ( tcx : TyCtxt < ' _ > , attr : & Attribute ) -> bool {
444386 debug ! ( "check_config(attr={:?})" , attr) ;
445387 let config = & tcx. sess . parse_sess . config ;
446388 debug ! ( "check_config: config={:?}" , config) ;
447- let ( mut cfg, mut except , mut label ) = ( None , false , false ) ;
389+ let mut cfg = None ;
448390 for item in attr. meta_item_list ( ) . unwrap_or_else ( Vec :: new) {
449391 if item. has_name ( CFG ) {
450392 let value = expect_associated_value ( tcx, & item) ;
451393 debug ! ( "check_config: searching for cfg {:?}" , value) ;
452394 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( ) ) ) ;
459397 }
460398 }
461399
462- if label && except {
463- tcx. sess . span_fatal ( attr. span , "must specify only one of: `label`, `except`" ) ;
464- }
465-
466400 match cfg {
467401 None => tcx. sess . span_fatal ( attr. span , "no cfg attribute" ) ,
468402 Some ( c) => c,
@@ -483,21 +417,18 @@ fn expect_associated_value(tcx: TyCtxt<'_>, item: &NestedMetaItem) -> Symbol {
483417 }
484418}
485419
486- // A visitor that collects all #[rustc_dirty]/#[ rustc_clean] attributes from
420+ // A visitor that collects all #[rustc_clean] attributes from
487421// the HIR. It is used to verify that we really ran checks for all annotated
488422// nodes.
489- pub struct FindAllAttrs < ' a , ' tcx > {
423+ pub struct FindAllAttrs < ' tcx > {
490424 tcx : TyCtxt < ' tcx > ,
491- attr_names : & ' a [ Symbol ] ,
492425 found_attrs : Vec < & ' tcx Attribute > ,
493426}
494427
495- impl FindAllAttrs < ' _ , ' tcx > {
428+ impl FindAllAttrs < ' tcx > {
496429 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 ;
501432 }
502433
503434 false
@@ -506,17 +437,14 @@ impl FindAllAttrs<'_, 'tcx> {
506437 fn report_unchecked_attrs ( & self , mut checked_attrs : FxHashSet < ast:: AttrId > ) {
507438 for attr in & self . found_attrs {
508439 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" ) ;
513441 checked_attrs. insert ( attr. id ) ;
514442 }
515443 }
516444 }
517445}
518446
519- impl intravisit:: Visitor < ' tcx > for FindAllAttrs < ' _ , ' tcx > {
447+ impl intravisit:: Visitor < ' tcx > for FindAllAttrs < ' tcx > {
520448 type Map = Map < ' tcx > ;
521449
522450 fn nested_visit_map ( & mut self ) -> intravisit:: NestedVisitorMap < Self :: Map > {
0 commit comments