11use rustc_ast:: token:: Token ;
22use rustc_ast:: tokenstream:: TokenStream ;
3- use rustc_ast:: { MetaItemInner , token} ;
3+ use rustc_ast:: { AttrStyle , token} ;
44use rustc_attr_parsing as attr;
5- use rustc_errors:: PResult ;
5+ use rustc_attr_parsing:: parser:: MetaItemOrLitParser ;
6+ use rustc_attr_parsing:: { AttributeParser , ParsedDescription , ShouldEmit , parse_cfg_entry} ;
67use rustc_expand:: base:: { DummyResult , ExpandResult , ExtCtxt , MacroExpanderResult } ;
8+ use rustc_feature:: AttributeTemplate ;
9+ use rustc_hir:: AttrPath ;
10+ use rustc_hir:: attrs:: CfgEntry ;
711use rustc_parse:: exp;
812use rustc_parse:: parser:: Parser ;
9- use rustc_span:: { Ident , Span , sym} ;
13+ use rustc_span:: { ErrorGuaranteed , Ident , Span , sym} ;
1014
1115use crate :: errors:: { CfgSelectNoMatches , CfgSelectUnreachable } ;
1216
1317enum CfgSelectPredicate {
14- Cfg ( MetaItemInner ) ,
18+ Cfg ( CfgEntry ) ,
1519 Wildcard ( Token ) ,
1620}
1721
1822#[ derive( Default ) ]
1923struct CfgSelectBranches {
2024 /// All the conditional branches.
21- pub reachable : Vec < ( MetaItemInner , TokenStream , Span ) > ,
25+ pub reachable : Vec < ( CfgEntry , TokenStream , Span ) > ,
2226 /// The first wildcard `_ => { ... }` branch.
2327 pub wildcard : Option < ( Token , TokenStream , Span ) > ,
2428 /// All branches after the first wildcard, including further wildcards.
@@ -29,12 +33,15 @@ struct CfgSelectBranches {
2933/// Selects the first arm whose predicate evaluates to true.
3034fn select_arm ( ecx : & ExtCtxt < ' _ > , branches : CfgSelectBranches ) -> Option < ( TokenStream , Span ) > {
3135 for ( cfg, tt, arm_span) in branches. reachable {
32- if attr:: cfg_matches (
33- & cfg,
36+ if attr:: eval_config_entry (
3437 & ecx. sess ,
38+ & cfg,
3539 ecx. current_expansion . lint_node_id ,
3640 Some ( ecx. ecfg . features ) ,
37- ) {
41+ ShouldEmit :: ErrorsAndLints ,
42+ )
43+ . as_bool ( )
44+ {
3845 return Some ( ( tt, arm_span) ) ;
3946 }
4047 }
@@ -47,7 +54,7 @@ pub(super) fn expand_cfg_select<'cx>(
4754 sp : Span ,
4855 tts : TokenStream ,
4956) -> MacroExpanderResult < ' cx > {
50- ExpandResult :: Ready ( match parse_cfg_select ( & mut ecx. new_parser_from_tts ( tts) ) {
57+ ExpandResult :: Ready ( match parse_cfg_select ( & mut ecx. new_parser_from_tts ( tts) , ecx ) {
5158 Ok ( branches) => {
5259 if let Some ( ( underscore, _, _) ) = branches. wildcard {
5360 // Warn for every unreachable predicate. We store the fully parsed branch for rustfmt.
@@ -75,22 +82,22 @@ pub(super) fn expand_cfg_select<'cx>(
7582 DummyResult :: any ( sp, guar)
7683 }
7784 }
78- Err ( err) => {
79- let guar = err. emit ( ) ;
80- DummyResult :: any ( sp, guar)
81- }
85+ Err ( guar) => DummyResult :: any ( sp, guar) ,
8286 } )
8387}
8488
85- fn parse_cfg_select < ' a > ( p : & mut Parser < ' a > ) -> PResult < ' a , CfgSelectBranches > {
89+ fn parse_cfg_select < ' a > (
90+ p : & mut Parser < ' a > ,
91+ cx : & ExtCtxt < ' _ > ,
92+ ) -> Result < CfgSelectBranches , ErrorGuaranteed > {
8693 let mut branches = CfgSelectBranches :: default ( ) ;
8794
8895 while p. token != token:: Eof {
8996 if p. eat_keyword ( exp ! ( Underscore ) ) {
9097 let underscore = p. prev_token ;
91- p. expect ( exp ! ( FatArrow ) ) ?;
98+ p. expect ( exp ! ( FatArrow ) ) . map_err ( |e| e . emit ( ) ) ?;
9299
93- let tts = p. parse_delimited_token_tree ( ) ?;
100+ let tts = p. parse_delimited_token_tree ( ) . map_err ( |e| e . emit ( ) ) ?;
94101 let span = underscore. span . to ( p. token . span ) ;
95102
96103 match branches. wildcard {
@@ -100,17 +107,36 @@ fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> {
100107 }
101108 }
102109 } else {
103- let meta_item = p. parse_meta_item_inner ( ) ?;
104- p. expect ( exp ! ( FatArrow ) ) ?;
110+ let meta = MetaItemOrLitParser :: parse_single ( p, ShouldEmit :: ErrorsAndLints )
111+ . map_err ( |diag| diag. emit ( ) ) ?;
112+ let cfg_span = meta. span ( ) ;
113+ let cfg = AttributeParser :: parse_single_args (
114+ cx. sess ,
115+ cfg_span,
116+ cfg_span,
117+ AttrStyle :: Inner ,
118+ AttrPath {
119+ segments : vec ! [ Ident :: from_str( "cfg_select" ) ] . into_boxed_slice ( ) ,
120+ span : cfg_span,
121+ } ,
122+ ParsedDescription :: Macro ,
123+ cfg_span,
124+ cx. current_expansion . lint_node_id ,
125+ Some ( cx. ecfg . features ) ,
126+ ShouldEmit :: ErrorsAndLints ,
127+ & meta,
128+ parse_cfg_entry,
129+ & AttributeTemplate :: default ( ) ,
130+ ) ?;
105131
106- let tts = p. parse_delimited_token_tree ( ) ?;
107- let span = meta_item. span ( ) . to ( p. token . span ) ;
132+ p. expect ( exp ! ( FatArrow ) ) . map_err ( |e| e. emit ( ) ) ?;
133+
134+ let tts = p. parse_delimited_token_tree ( ) . map_err ( |e| e. emit ( ) ) ?;
135+ let span = cfg_span. to ( p. token . span ) ;
108136
109137 match branches. wildcard {
110- None => branches. reachable . push ( ( meta_item, tts, span) ) ,
111- Some ( _) => {
112- branches. unreachable . push ( ( CfgSelectPredicate :: Cfg ( meta_item) , tts, span) )
113- }
138+ None => branches. reachable . push ( ( cfg, tts, span) ) ,
139+ Some ( _) => branches. unreachable . push ( ( CfgSelectPredicate :: Cfg ( cfg) , tts, span) ) ,
114140 }
115141 }
116142 }
0 commit comments