Skip to content

Commit 8605944

Browse files
committed
Properly recover from trailing attr in body
When encountering an attribute in a body, we try to recover from an attribute on an expression (as opposed to a statement). We need to properly clean up when the attribute is at the end of the body where a tail expression would be. Fix #118164.
1 parent 73bc121 commit 8605944

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+18-2
Original file line numberDiff line numberDiff line change
@@ -772,12 +772,27 @@ impl<'a> Parser<'a> {
772772
&& let ast::AttrKind::Normal(attr_kind) = &attr.kind
773773
&& let [segment] = &attr_kind.item.path.segments[..]
774774
&& segment.ident.name == sym::cfg
775-
&& let Ok(next_attr) = snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
775+
&& let next_attr = match snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
776+
{
777+
Ok(next_attr) => next_attr,
778+
Err(inner_err) => {
779+
err.cancel();
780+
inner_err.cancel();
781+
return;
782+
}
783+
}
776784
&& let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
777785
&& let [next_segment] = &next_attr_kind.item.path.segments[..]
778786
&& segment.ident.name == sym::cfg
779-
&& let Ok(next_expr) = snapshot.parse_expr()
780787
{
788+
let next_expr = match snapshot.parse_expr() {
789+
Ok(next_expr) => next_expr,
790+
Err(inner_err) => {
791+
err.cancel();
792+
inner_err.cancel();
793+
return;
794+
}
795+
};
781796
// We have for sure
782797
// #[cfg(..)]
783798
// expr
@@ -819,6 +834,7 @@ impl<'a> Parser<'a> {
819834
}
820835
err.emit();
821836
}
837+
822838
fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool {
823839
let sm = self.sess.source_map();
824840
match (&self.prev_token.kind, &self.token.kind) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Issue #118164: recovery path leaving unemitted error behind
2+
fn bar() -> String {
3+
#[cfg(feature = )]
4+
[1, 2, 3].iter().map().collect::<String>()
5+
#[attr] //~ ERROR expected statement after outer attribute
6+
}
7+
fn main() {
8+
let _ = bar();
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected statement after outer attribute
2+
--> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
3+
|
4+
LL | #[attr]
5+
| ^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)