99//! - `#[rustc_clean(cfg="rev2")]` same as above, except that the
1010//! fingerprints must be the SAME (along with all other fingerprints).
1111//!
12+ //! - `#[rustc_clean(cfg="rev2", loaded_from_disk='typeck")]` asserts that
13+ //! the query result for `DepNode::typeck(X)` was actually
14+ //! loaded from disk (not just marked green). This can be useful
15+ //! to ensure that a test is actually exercising the deserialization
16+ //! logic for a particular query result. This can be combined with
17+ //! `except`
18+ //!
1219//! Errors are reported if we are in the suitable configuration but
1320//! the required condition is not met.
1421
@@ -28,6 +35,7 @@ use rustc_span::Span;
2835use std:: iter:: FromIterator ;
2936use std:: vec:: Vec ;
3037
38+ const LOADED_FROM_DISK : Symbol = sym:: loaded_from_disk;
3139const EXCEPT : Symbol = sym:: except;
3240const CFG : Symbol = sym:: cfg;
3341
@@ -124,6 +132,7 @@ type Labels = FxHashSet<String>;
124132struct Assertion {
125133 clean : Labels ,
126134 dirty : Labels ,
135+ loaded_from_disk : Labels ,
127136}
128137
129138pub fn check_dirty_clean_annotations ( tcx : TyCtxt < ' _ > ) {
@@ -174,6 +183,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
174183 fn assertion_auto ( & mut self , item_id : LocalDefId , attr : & Attribute ) -> Assertion {
175184 let ( name, mut auto) = self . auto_labels ( item_id, attr) ;
176185 let except = self . except ( attr) ;
186+ let loaded_from_disk = self . loaded_from_disk ( attr) ;
177187 for e in except. iter ( ) {
178188 if !auto. remove ( e) {
179189 let msg = format ! (
@@ -183,7 +193,19 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
183193 self . tcx . sess . span_fatal ( attr. span , & msg) ;
184194 }
185195 }
186- Assertion { clean : auto, dirty : except }
196+ Assertion { clean : auto, dirty : except, loaded_from_disk }
197+ }
198+
199+ /// `loaded_from_disk=` attribute value
200+ fn loaded_from_disk ( & self , attr : & Attribute ) -> Labels {
201+ for item in attr. meta_item_list ( ) . unwrap_or_else ( Vec :: new) {
202+ if item. has_name ( LOADED_FROM_DISK ) {
203+ let value = expect_associated_value ( self . tcx , & item) ;
204+ return self . resolve_labels ( & item, value) ;
205+ }
206+ }
207+ // If `loaded_from_disk=` is not specified, don't assert anything
208+ Labels :: default ( )
187209 }
188210
189211 /// `except=` attribute value
@@ -332,6 +354,18 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
332354 }
333355 }
334356
357+ fn assert_loaded_from_disk ( & self , item_span : Span , dep_node : DepNode ) {
358+ debug ! ( "assert_loaded_from_disk({:?})" , dep_node) ;
359+
360+ if !self . tcx . dep_graph . debug_was_loaded_from_disk ( dep_node) {
361+ let dep_node_str = self . dep_node_str ( & dep_node) ;
362+ self . tcx . sess . span_err (
363+ item_span,
364+ & format ! ( "`{}` should have been loaded from disk but it was not" , dep_node_str) ,
365+ ) ;
366+ }
367+ }
368+
335369 fn check_item ( & mut self , item_id : LocalDefId , item_span : Span ) {
336370 let def_path_hash = self . tcx . def_path_hash ( item_id. to_def_id ( ) ) ;
337371 for attr in self . tcx . get_attrs ( item_id. to_def_id ( ) ) . iter ( ) {
@@ -348,6 +382,10 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
348382 let dep_node = DepNode :: from_label_string ( self . tcx , & label, def_path_hash) . unwrap ( ) ;
349383 self . assert_dirty ( item_span, dep_node) ;
350384 }
385+ for label in assertion. loaded_from_disk {
386+ let dep_node = DepNode :: from_label_string ( self . tcx , & label, def_path_hash) . unwrap ( ) ;
387+ self . assert_loaded_from_disk ( item_span, dep_node) ;
388+ }
351389 }
352390 }
353391}
@@ -382,7 +420,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
382420 let value = expect_associated_value ( tcx, & item) ;
383421 debug ! ( "check_config: searching for cfg {:?}" , value) ;
384422 cfg = Some ( config. contains ( & ( value, None ) ) ) ;
385- } else if !item. has_name ( EXCEPT ) {
423+ } else if !( item. has_name ( EXCEPT ) || item . has_name ( LOADED_FROM_DISK ) ) {
386424 tcx. sess . span_err ( attr. span , & format ! ( "unknown item `{}`" , item. name_or_empty( ) ) ) ;
387425 }
388426 }
0 commit comments