@@ -4,15 +4,15 @@ use rustc_ast::{LitIntType, LitKind, MetaItemLit};
44use rustc_hir:: LangItem ;
55use rustc_hir:: attrs:: {
66 BorrowckGraphvizFormatKind , CguFields , CguKind , DivergingBlockBehavior ,
7- DivergingFallbackBehavior , RustcCleanAttribute , RustcCleanQueries , RustcMirKind ,
7+ DivergingFallbackBehavior , RDRFields , RustcCleanAttribute , RustcCleanQueries , RustcMirKind ,
88} ;
99use rustc_span:: Symbol ;
1010
1111use super :: prelude:: * ;
1212use super :: util:: parse_single_integer;
1313use crate :: errors;
1414use crate :: session_diagnostics:: {
15- AttributeRequiresOpt , CguFieldsMissing , RustcScalableVectorCountOutOfRange , UnknownLangItem ,
15+ AttributeRequiresOpt , FieldsMissing , RustcScalableVectorCountOutOfRange , UnknownLangItem ,
1616} ;
1717
1818pub ( crate ) struct RustcMainParser ;
@@ -250,11 +250,11 @@ fn parse_cgu_fields<S: Stage>(
250250 }
251251
252252 let Some ( ( cfg, _) ) = cfg else {
253- cx. emit_err ( CguFieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: cfg } ) ;
253+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: cfg } ) ;
254254 return None ;
255255 } ;
256256 let Some ( ( module, _) ) = module else {
257- cx. emit_err ( CguFieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: module } ) ;
257+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: module } ) ;
258258 return None ;
259259 } ;
260260 let kind = if let Some ( ( kind, span) ) = kind {
@@ -274,11 +274,7 @@ fn parse_cgu_fields<S: Stage>(
274274 } else {
275275 // return None so that an unwrap for the attributes that need it is ok.
276276 if accepts_kind {
277- cx. emit_err ( CguFieldsMissing {
278- span : args. span ,
279- name : & cx. attr_path ,
280- field : sym:: kind,
281- } ) ;
277+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: kind } ) ;
282278 return None ;
283279 } ;
284280
@@ -288,6 +284,95 @@ fn parse_cgu_fields<S: Stage>(
288284 Some ( ( cfg, module, kind) )
289285}
290286
287+ fn parse_rdr_fields < S : Stage > (
288+ cx : & mut AcceptContext < ' _ , ' _ , S > ,
289+ args : & ArgParser ,
290+ ) -> Option < ( Symbol , Symbol ) > {
291+ let args = cx. expect_list ( args, cx. attr_span ) ?;
292+
293+ let mut cfg = None :: < ( Symbol , Span ) > ;
294+ let mut crate_name = None :: < ( Symbol , Span ) > ;
295+
296+ for arg in args. mixed ( ) {
297+ let Some ( arg) = arg. meta_item ( ) else {
298+ cx. adcx ( ) . expected_name_value ( args. span , None ) ;
299+ continue ;
300+ } ;
301+
302+ let res = match arg. ident ( ) . map ( |i| i. name ) {
303+ Some ( sym:: cfg) => & mut cfg,
304+ Some ( sym:: crate_name) => & mut crate_name,
305+ _ => {
306+ cx. adcx ( )
307+ . expected_specific_argument ( arg. path ( ) . span ( ) , & [ sym:: cfg, sym:: crate_name] ) ;
308+ continue ;
309+ }
310+ } ;
311+
312+ let Some ( i) = arg. args ( ) . name_value ( ) else {
313+ cx. adcx ( ) . expected_name_value ( arg. span ( ) , None ) ;
314+ continue ;
315+ } ;
316+
317+ let Some ( str) = i. value_as_str ( ) else {
318+ cx. adcx ( ) . expected_string_literal ( i. value_span , Some ( i. value_as_lit ( ) ) ) ;
319+ continue ;
320+ } ;
321+
322+ if res. is_some ( ) {
323+ cx. adcx ( ) . duplicate_key ( arg. span ( ) , arg. ident ( ) . unwrap ( ) . name ) ;
324+ continue ;
325+ }
326+
327+ * res = Some ( ( str, i. value_span ) ) ;
328+ }
329+
330+ let Some ( ( cfg, _) ) = cfg else {
331+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: cfg } ) ;
332+ return None ;
333+ } ;
334+ let Some ( ( crate_name, _) ) = crate_name else {
335+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: crate_name } ) ;
336+ return None ;
337+ } ;
338+
339+ Some ( ( cfg, crate_name) )
340+ }
341+
342+ #[ derive( Default ) ]
343+ pub ( crate ) struct RustcRDRTestAttributeParser {
344+ items : ThinVec < ( Span , RDRFields ) > ,
345+ }
346+
347+ impl < S : Stage > AttributeParser < S > for RustcRDRTestAttributeParser {
348+ const ATTRIBUTES : AcceptMapping < Self , S > = & [
349+ (
350+ & [ sym:: rustc_public_hash_changed] ,
351+ template ! ( List : & [ r#"cfg = "...", crate_name = "...""# ] ) ,
352+ |this, cx, args| {
353+ this. items . extend ( parse_rdr_fields ( cx, args) . map ( |( cfg, crate_name) | {
354+ ( cx. attr_span , RDRFields { cfg, crate_name, changed : false } )
355+ } ) ) ;
356+ } ,
357+ ) ,
358+ (
359+ & [ sym:: rustc_public_hash_unchanged] ,
360+ template ! ( List : & [ r#"cfg = "...", crate_name = "...""# ] ) ,
361+ |this, cx, args| {
362+ this. items . extend ( parse_rdr_fields ( cx, args) . map ( |( cfg, crate_name) | {
363+ ( cx. attr_span , RDRFields { cfg, crate_name, changed : true } )
364+ } ) ) ;
365+ } ,
366+ ) ,
367+ ] ;
368+
369+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( & [ Allow ( Target :: Crate ) ] ) ;
370+
371+ fn finalize ( self , _cx : & FinalizeContext < ' _ , ' _ , S > ) -> Option < AttributeKind > {
372+ Some ( AttributeKind :: RustcRDRTestAttr ( self . items ) )
373+ }
374+ }
375+
291376#[ derive( Default ) ]
292377pub ( crate ) struct RustcCguTestAttributeParser {
293378 items : ThinVec < ( Span , CguFields ) > ,
0 commit comments