9
9
//! - `#[rustc_clean(cfg="rev2")]` same as above, except that the
10
10
//! fingerprints must be the SAME (along with all other fingerprints).
11
11
//!
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
+ //!
12
19
//! Errors are reported if we are in the suitable configuration but
13
20
//! the required condition is not met.
14
21
@@ -28,6 +35,7 @@ use rustc_span::Span;
28
35
use std:: iter:: FromIterator ;
29
36
use std:: vec:: Vec ;
30
37
38
+ const LOADED_FROM_DISK : Symbol = sym:: loaded_from_disk;
31
39
const EXCEPT : Symbol = sym:: except;
32
40
const CFG : Symbol = sym:: cfg;
33
41
@@ -124,6 +132,7 @@ type Labels = FxHashSet<String>;
124
132
struct Assertion {
125
133
clean : Labels ,
126
134
dirty : Labels ,
135
+ loaded_from_disk : Labels ,
127
136
}
128
137
129
138
pub fn check_dirty_clean_annotations ( tcx : TyCtxt < ' _ > ) {
@@ -174,6 +183,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
174
183
fn assertion_auto ( & mut self , item_id : LocalDefId , attr : & Attribute ) -> Assertion {
175
184
let ( name, mut auto) = self . auto_labels ( item_id, attr) ;
176
185
let except = self . except ( attr) ;
186
+ let loaded_from_disk = self . loaded_from_disk ( attr) ;
177
187
for e in except. iter ( ) {
178
188
if !auto. remove ( e) {
179
189
let msg = format ! (
@@ -183,7 +193,19 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
183
193
self . tcx . sess . span_fatal ( attr. span , & msg) ;
184
194
}
185
195
}
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 ( )
187
209
}
188
210
189
211
/// `except=` attribute value
@@ -332,6 +354,18 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
332
354
}
333
355
}
334
356
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
+
335
369
fn check_item ( & mut self , item_id : LocalDefId , item_span : Span ) {
336
370
let def_path_hash = self . tcx . def_path_hash ( item_id. to_def_id ( ) ) ;
337
371
for attr in self . tcx . get_attrs ( item_id. to_def_id ( ) ) . iter ( ) {
@@ -348,6 +382,10 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
348
382
let dep_node = DepNode :: from_label_string ( self . tcx , & label, def_path_hash) . unwrap ( ) ;
349
383
self . assert_dirty ( item_span, dep_node) ;
350
384
}
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
+ }
351
389
}
352
390
}
353
391
}
@@ -382,7 +420,7 @@ fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
382
420
let value = expect_associated_value ( tcx, & item) ;
383
421
debug ! ( "check_config: searching for cfg {:?}" , value) ;
384
422
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 ) ) {
386
424
tcx. sess . span_err ( attr. span , & format ! ( "unknown item `{}`" , item. name_or_empty( ) ) ) ;
387
425
}
388
426
}
0 commit comments