Skip to content

Commit 3f88370

Browse files
committed
avoid ICE when cfg_eval reparse recovers no annotatable
1 parent 7c8c136 commit 3f88370

2 files changed

Lines changed: 19 additions & 31 deletions

File tree

compiler/rustc_builtin_macros/src/cfg_eval.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,40 +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())
123+
parser.parse_foreign_item(ForceCollect::Yes)?.flatten().and_then(|item| {
124+
self.flat_map_foreign_item(item).pop().map(Annotatable::ForeignItem)
125+
})
127126
}
128127
Annotatable::Stmt(_) => {
129128
let stmt =
130129
parser.parse_stmt_without_recovery(false, ForceCollect::Yes, false)?;
131-
Annotatable::Stmt(Box::new(self.flat_map_stmt(stmt).pop().unwrap()))
130+
self.flat_map_stmt(stmt).pop().map(|stmt| Annotatable::Stmt(Box::new(stmt)))
132131
}
133132
Annotatable::Expr(_) => {
134133
let mut expr = parser.parse_expr_force_collect()?;
135134
self.visit_expr(&mut expr);
136-
Annotatable::Expr(expr)
135+
Some(Annotatable::Expr(expr))
137136
}
138137
_ => unreachable!(),
139138
}
140139
};
141140

142141
match res {
143-
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,
144146
Err(err) => {
145147
err.emit();
146148
annotatable

tests/crashes/148891.rs

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)