23
23
//! Errors are reported if we are in the suitable configuration but
24
24
//! the required condition is not met.
25
25
//!
26
- //! The `#[rustc_metadata_dirty]` and `#[rustc_metadata_clean]` attributes
27
- //! can be used to check the incremental compilation hash (ICH) values of
28
- //! metadata exported in rlibs.
29
- //!
30
- //! - If a node is marked with `#[rustc_metadata_clean(cfg="rev2")]` we
31
- //! check that the metadata hash for that node is the same for "rev2"
32
- //! it was for "rev1".
33
- //! - If a node is marked with `#[rustc_metadata_dirty(cfg="rev2")]` we
34
- //! check that the metadata hash for that node is *different* for "rev2"
35
- //! than it was for "rev1".
36
- //!
37
- //! Note that the metadata-testing attributes must never specify the
38
- //! first revision. This would lead to a crash since there is no
39
- //! previous revision to compare things to.
40
- //!
41
26
42
27
use std:: collections:: HashSet ;
43
28
use std:: iter:: FromIterator ;
@@ -49,10 +34,9 @@ use rustc::hir::map::Node as HirNode;
49
34
use rustc:: hir:: def_id:: DefId ;
50
35
use rustc:: hir:: itemlikevisit:: ItemLikeVisitor ;
51
36
use rustc:: hir:: intravisit;
52
- use rustc:: ich:: { Fingerprint , ATTR_DIRTY , ATTR_CLEAN , ATTR_DIRTY_METADATA ,
53
- ATTR_CLEAN_METADATA } ;
37
+ use rustc:: ich:: { ATTR_DIRTY , ATTR_CLEAN } ;
54
38
use syntax:: ast:: { self , Attribute , NestedMetaItem } ;
55
- use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
39
+ use rustc_data_structures:: fx:: FxHashSet ;
56
40
use syntax_pos:: Span ;
57
41
use rustc:: ty:: TyCtxt ;
58
42
@@ -553,157 +537,6 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for DirtyCleanVisitor<'a, 'tcx> {
553
537
}
554
538
}
555
539
556
- pub fn check_dirty_clean_metadata < ' a , ' tcx > (
557
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
558
- prev_metadata_hashes : & FxHashMap < DefId , Fingerprint > ,
559
- current_metadata_hashes : & FxHashMap < DefId , Fingerprint > )
560
- {
561
- if !tcx. sess . opts . debugging_opts . query_dep_graph {
562
- return ;
563
- }
564
-
565
- tcx. dep_graph . with_ignore ( ||{
566
- let krate = tcx. hir . krate ( ) ;
567
- let mut dirty_clean_visitor = DirtyCleanMetadataVisitor {
568
- tcx,
569
- prev_metadata_hashes,
570
- current_metadata_hashes,
571
- checked_attrs : FxHashSet ( ) ,
572
- } ;
573
- intravisit:: walk_crate ( & mut dirty_clean_visitor, krate) ;
574
-
575
- let mut all_attrs = FindAllAttrs {
576
- tcx,
577
- attr_names : vec ! [ ATTR_DIRTY_METADATA , ATTR_CLEAN_METADATA ] ,
578
- found_attrs : vec ! [ ] ,
579
- } ;
580
- intravisit:: walk_crate ( & mut all_attrs, krate) ;
581
-
582
- // Note that we cannot use the existing "unused attribute"-infrastructure
583
- // here, since that is running before trans. This is also the reason why
584
- // all trans-specific attributes are `Whitelisted` in syntax::feature_gate.
585
- all_attrs. report_unchecked_attrs ( & dirty_clean_visitor. checked_attrs ) ;
586
- } ) ;
587
- }
588
-
589
- pub struct DirtyCleanMetadataVisitor < ' a , ' tcx : ' a , ' m > {
590
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
591
- prev_metadata_hashes : & ' m FxHashMap < DefId , Fingerprint > ,
592
- current_metadata_hashes : & ' m FxHashMap < DefId , Fingerprint > ,
593
- checked_attrs : FxHashSet < ast:: AttrId > ,
594
- }
595
-
596
- impl < ' a , ' tcx , ' m > intravisit:: Visitor < ' tcx > for DirtyCleanMetadataVisitor < ' a , ' tcx , ' m > {
597
-
598
- fn nested_visit_map < ' this > ( & ' this mut self ) -> intravisit:: NestedVisitorMap < ' this , ' tcx > {
599
- intravisit:: NestedVisitorMap :: All ( & self . tcx . hir )
600
- }
601
-
602
- fn visit_item ( & mut self , item : & ' tcx hir:: Item ) {
603
- self . check_item ( item. id , item. span ) ;
604
- intravisit:: walk_item ( self , item) ;
605
- }
606
-
607
- fn visit_variant ( & mut self ,
608
- variant : & ' tcx hir:: Variant ,
609
- generics : & ' tcx hir:: Generics ,
610
- parent_id : ast:: NodeId ) {
611
- if let Some ( e) = variant. node . disr_expr {
612
- self . check_item ( e. node_id , variant. span ) ;
613
- }
614
-
615
- intravisit:: walk_variant ( self , variant, generics, parent_id) ;
616
- }
617
-
618
- fn visit_variant_data ( & mut self ,
619
- variant_data : & ' tcx hir:: VariantData ,
620
- _: ast:: Name ,
621
- _: & ' tcx hir:: Generics ,
622
- _parent_id : ast:: NodeId ,
623
- span : Span ) {
624
- if self . tcx . hir . find ( variant_data. id ( ) ) . is_some ( ) {
625
- // VariantData that represent structs or tuples don't have a
626
- // separate entry in the HIR map and checking them would error,
627
- // so only check if this is an enum or union variant.
628
- self . check_item ( variant_data. id ( ) , span) ;
629
- }
630
-
631
- intravisit:: walk_struct_def ( self , variant_data) ;
632
- }
633
-
634
- fn visit_trait_item ( & mut self , item : & ' tcx hir:: TraitItem ) {
635
- self . check_item ( item. id , item. span ) ;
636
- intravisit:: walk_trait_item ( self , item) ;
637
- }
638
-
639
- fn visit_impl_item ( & mut self , item : & ' tcx hir:: ImplItem ) {
640
- self . check_item ( item. id , item. span ) ;
641
- intravisit:: walk_impl_item ( self , item) ;
642
- }
643
-
644
- fn visit_foreign_item ( & mut self , i : & ' tcx hir:: ForeignItem ) {
645
- self . check_item ( i. id , i. span ) ;
646
- intravisit:: walk_foreign_item ( self , i) ;
647
- }
648
-
649
- fn visit_struct_field ( & mut self , s : & ' tcx hir:: StructField ) {
650
- self . check_item ( s. id , s. span ) ;
651
- intravisit:: walk_struct_field ( self , s) ;
652
- }
653
- }
654
-
655
- impl < ' a , ' tcx , ' m > DirtyCleanMetadataVisitor < ' a , ' tcx , ' m > {
656
-
657
- fn check_item ( & mut self , item_id : ast:: NodeId , item_span : Span ) {
658
- let def_id = self . tcx . hir . local_def_id ( item_id) ;
659
-
660
- for attr in self . tcx . get_attrs ( def_id) . iter ( ) {
661
- if attr. check_name ( ATTR_DIRTY_METADATA ) {
662
- if check_config ( self . tcx , attr) {
663
- if self . checked_attrs . insert ( attr. id ) {
664
- self . assert_state ( false , def_id, item_span) ;
665
- }
666
- }
667
- } else if attr. check_name ( ATTR_CLEAN_METADATA ) {
668
- if check_config ( self . tcx , attr) {
669
- if self . checked_attrs . insert ( attr. id ) {
670
- self . assert_state ( true , def_id, item_span) ;
671
- }
672
- }
673
- }
674
- }
675
- }
676
-
677
- fn assert_state ( & self , should_be_clean : bool , def_id : DefId , span : Span ) {
678
- let item_path = self . tcx . item_path_str ( def_id) ;
679
- debug ! ( "assert_state({})" , item_path) ;
680
-
681
- if let Some ( & prev_hash) = self . prev_metadata_hashes . get ( & def_id) {
682
- let hashes_are_equal = prev_hash == self . current_metadata_hashes [ & def_id] ;
683
-
684
- if should_be_clean && !hashes_are_equal {
685
- self . tcx . sess . span_err (
686
- span,
687
- & format ! ( "Metadata hash of `{}` is dirty, but should be clean" ,
688
- item_path) ) ;
689
- }
690
-
691
- let should_be_dirty = !should_be_clean;
692
- if should_be_dirty && hashes_are_equal {
693
- self . tcx . sess . span_err (
694
- span,
695
- & format ! ( "Metadata hash of `{}` is clean, but should be dirty" ,
696
- item_path) ) ;
697
- }
698
- } else {
699
- self . tcx . sess . span_err (
700
- span,
701
- & format ! ( "Could not find previous metadata hash of `{}`" ,
702
- item_path) ) ;
703
- }
704
- }
705
- }
706
-
707
540
/// Given a `#[rustc_dirty]` or `#[rustc_clean]` attribute, scan
708
541
/// for a `cfg="foo"` attribute and check whether we have a cfg
709
542
/// flag called `foo`.
@@ -759,7 +592,6 @@ fn expect_associated_value(tcx: TyCtxt, item: &NestedMetaItem) -> ast::Name {
759
592
}
760
593
}
761
594
762
-
763
595
// A visitor that collects all #[rustc_dirty]/#[rustc_clean] attributes from
764
596
// the HIR. It is used to verfiy that we really ran checks for all annotated
765
597
// nodes.
0 commit comments