Skip to content
/ rust Public
forked from rust-lang/rust

Commit 14e5371

Browse files
committed
avoid ICE when cfg_eval reparse recovers no annotatable
1 parent 2d10922 commit 14e5371

1 file changed

Lines changed: 23 additions & 22 deletions

File tree

compiler/rustc_builtin_macros/src/cfg_eval.rs

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)