@@ -5,15 +5,15 @@ use rustc_feature::AttributeStability;
55use rustc_hir:: LangItem ;
66use rustc_hir:: attrs:: {
77 BorrowckGraphvizFormatKind , CguFields , CguKind , DivergingBlockBehavior ,
8- DivergingFallbackBehavior , RustcCleanAttribute , RustcCleanQueries , RustcMirKind ,
8+ DivergingFallbackBehavior , RDRFields , RustcCleanAttribute , RustcCleanQueries , RustcMirKind ,
99} ;
1010use rustc_span:: Symbol ;
1111
1212use super :: prelude:: * ;
1313use super :: util:: parse_single_integer;
1414use crate :: errors;
1515use crate :: session_diagnostics:: {
16- AttributeRequiresOpt , CguFieldsMissing , RustcScalableVectorCountOutOfRange , UnknownLangItem ,
16+ AttributeRequiresOpt , FieldsMissing , RustcScalableVectorCountOutOfRange , UnknownLangItem ,
1717} ;
1818
1919pub ( crate ) struct RustcMainParser ;
@@ -226,11 +226,11 @@ fn parse_cgu_fields(
226226 }
227227
228228 let Some ( ( cfg, _) ) = cfg else {
229- cx. emit_err ( CguFieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: cfg } ) ;
229+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: cfg } ) ;
230230 return None ;
231231 } ;
232232 let Some ( ( module, _) ) = module else {
233- cx. emit_err ( CguFieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: module } ) ;
233+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: module } ) ;
234234 return None ;
235235 } ;
236236 let kind = if let Some ( ( kind, span) ) = kind {
@@ -250,11 +250,7 @@ fn parse_cgu_fields(
250250 } else {
251251 // return None so that an unwrap for the attributes that need it is ok.
252252 if accepts_kind {
253- cx. emit_err ( CguFieldsMissing {
254- span : args. span ,
255- name : & cx. attr_path ,
256- field : sym:: kind,
257- } ) ;
253+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: kind } ) ;
258254 return None ;
259255 } ;
260256
@@ -264,6 +260,87 @@ fn parse_cgu_fields(
264260 Some ( ( cfg, module, kind) )
265261}
266262
263+ fn parse_rdr_fields ( cx : & mut AcceptContext < ' _ , ' _ > , args : & ArgParser ) -> Option < ( Symbol , Symbol ) > {
264+ let args = cx. expect_list ( args, cx. attr_span ) ?;
265+
266+ let mut cfg = None :: < ( Symbol , Span ) > ;
267+ let mut crate_name = None :: < ( Symbol , Span ) > ;
268+
269+ for arg in args. mixed ( ) {
270+ let Some ( ( ident, arg) ) = cx. expect_name_value ( arg, arg. span ( ) , None ) else {
271+ continue ;
272+ } ;
273+
274+ let res = match ident. name {
275+ sym:: cfg => & mut cfg,
276+ sym:: crate_name => & mut crate_name,
277+ _ => {
278+ cx. adcx ( ) . expected_specific_argument ( ident. span , & [ sym:: cfg, sym:: crate_name] ) ;
279+ continue ;
280+ }
281+ } ;
282+
283+ let Some ( str) = arg. value_as_str ( ) else {
284+ cx. adcx ( ) . expected_string_literal ( arg. value_span , Some ( arg. value_as_lit ( ) ) ) ;
285+ continue ;
286+ } ;
287+
288+ if res. is_some ( ) {
289+ cx. adcx ( ) . duplicate_key ( ident. span . to ( arg. args_span ( ) ) , ident. name ) ;
290+ continue ;
291+ }
292+
293+ * res = Some ( ( str, arg. value_span ) ) ;
294+ }
295+
296+ let Some ( ( cfg, _) ) = cfg else {
297+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: cfg } ) ;
298+ return None ;
299+ } ;
300+ let Some ( ( crate_name, _) ) = crate_name else {
301+ cx. emit_err ( FieldsMissing { span : args. span , name : & cx. attr_path , field : sym:: crate_name } ) ;
302+ return None ;
303+ } ;
304+
305+ Some ( ( cfg, crate_name) )
306+ }
307+
308+ #[ derive( Default ) ]
309+ pub ( crate ) struct RustcRDRTestAttributeParser {
310+ items : ThinVec < ( Span , RDRFields ) > ,
311+ }
312+
313+ impl AttributeParser for RustcRDRTestAttributeParser {
314+ const ATTRIBUTES : AcceptMapping < Self > = & [
315+ (
316+ & [ sym:: rustc_public_hash_changed] ,
317+ template ! ( List : & [ r#"cfg = "...", crate_name = "...""# ] ) ,
318+ unstable ! ( rustc_attrs) ,
319+ |this, cx, args| {
320+ this. items . extend ( parse_rdr_fields ( cx, args) . map ( |( cfg, crate_name) | {
321+ ( cx. attr_span , RDRFields { cfg, crate_name, changed : true } )
322+ } ) ) ;
323+ } ,
324+ ) ,
325+ (
326+ & [ sym:: rustc_public_hash_unchanged] ,
327+ template ! ( List : & [ r#"cfg = "...", crate_name = "...""# ] ) ,
328+ unstable ! ( rustc_attrs) ,
329+ |this, cx, args| {
330+ this. items . extend ( parse_rdr_fields ( cx, args) . map ( |( cfg, crate_name) | {
331+ ( cx. attr_span , RDRFields { cfg, crate_name, changed : false } )
332+ } ) ) ;
333+ } ,
334+ ) ,
335+ ] ;
336+
337+ const ALLOWED_TARGETS : AllowedTargets = AllowedTargets :: AllowList ( & [ Allow ( Target :: Crate ) ] ) ;
338+
339+ fn finalize ( self , _cx : & FinalizeContext < ' _ , ' _ > ) -> Option < AttributeKind > {
340+ Some ( AttributeKind :: RustcRDRTestAttr ( self . items ) )
341+ }
342+ }
343+
267344#[ derive( Default ) ]
268345pub ( crate ) struct RustcCguTestAttributeParser {
269346 items : ThinVec < ( Span , CguFields ) > ,
0 commit comments