@@ -107,41 +107,42 @@ impl CfgEval<'_> {
107107 // our attribute target will correctly configure the tokens as well.
108108 let mut parser = Parser :: new ( & self . 0 . sess . psess , orig_tokens, None ) ;
109109 parser. capture_cfg = true ;
110- let res: PResult < ' _ , Annotatable > = try {
111- match annotatable {
112- Annotatable :: Item ( _) => {
113- let item =
114- parser. parse_item ( ForceCollect :: Yes , AllowConstBlockItems :: Yes ) ?. unwrap ( ) ;
115- Annotatable :: Item ( self . flat_map_item ( item) . pop ( ) . unwrap ( ) )
116- }
110+ let res: PResult < ' _ , Option < Annotatable > > = try {
111+ match & annotatable {
112+ Annotatable :: Item ( _) => parser
113+ . parse_item ( ForceCollect :: Yes , AllowConstBlockItems :: Yes ) ?
114+ . and_then ( |item| self . flat_map_item ( item) . pop ( ) . map ( Annotatable :: Item ) ) ,
117115 Annotatable :: AssocItem ( _, ctxt) => {
118- let item = parser. parse_trait_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ;
119- Annotatable :: AssocItem (
120- self . flat_map_assoc_item ( item , ctxt ) . pop ( ) . unwrap ( ) ,
121- ctxt ,
122- )
116+ parser. parse_trait_item ( ForceCollect :: Yes ) ?. flatten ( ) . and_then ( |item| {
117+ self . flat_map_assoc_item ( item , * ctxt )
118+ . pop ( )
119+ . map ( |item| Annotatable :: AssocItem ( item , * ctxt ) )
120+ } )
123121 }
124122 Annotatable :: ForeignItem ( _) => {
125- let item = parser. parse_foreign_item ( ForceCollect :: Yes ) ?. unwrap ( ) . unwrap ( ) ;
126- Annotatable :: ForeignItem ( self . flat_map_foreign_item ( item) . pop ( ) . unwrap ( ) )
127- }
128- Annotatable :: Stmt ( _) => {
129- let stmt = parser
130- . parse_stmt_without_recovery ( false , ForceCollect :: Yes , false ) ?
131- . unwrap ( ) ;
132- Annotatable :: Stmt ( Box :: new ( self . flat_map_stmt ( stmt) . pop ( ) . unwrap ( ) ) )
123+ parser. parse_foreign_item ( ForceCollect :: Yes ) ?. flatten ( ) . and_then ( |item| {
124+ self . flat_map_foreign_item ( item) . pop ( ) . map ( Annotatable :: ForeignItem )
125+ } )
133126 }
127+ Annotatable :: Stmt ( _) => parser
128+ . parse_stmt_without_recovery ( false , ForceCollect :: Yes , false ) ?
129+ . and_then ( |stmt| {
130+ self . flat_map_stmt ( stmt) . pop ( ) . map ( |stmt| Annotatable :: Stmt ( Box :: new ( stmt) ) )
131+ } ) ,
134132 Annotatable :: Expr ( _) => {
135133 let mut expr = parser. parse_expr_force_collect ( ) ?;
136134 self . visit_expr ( & mut expr) ;
137- Annotatable :: Expr ( expr)
135+ Some ( Annotatable :: Expr ( expr) )
138136 }
139137 _ => unreachable ! ( ) ,
140138 }
141139 } ;
142140
143141 match res {
144- Ok ( ann) => ann,
142+ Ok ( Some ( ann) ) => ann,
143+ // Parser recovery may emit errors without reconstructing an annotatable.
144+ // Keep the original node so cfg-eval stays best-effort instead of ICEing.
145+ Ok ( None ) => annotatable,
145146 Err ( err) => {
146147 err. emit ( ) ;
147148 annotatable
0 commit comments