Skip to content

Commit 00f5e09

Browse files
authored
Rollup merge of rust-lang#118182 - estebank:issue-118164, r=davidtwco
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 rust-lang#118164, fix rust-lang#118575.
2 parents 37f8c01 + a5d9def commit 00f5e09

File tree

3 files changed

+53
-2
lines changed

3 files changed

+53
-2
lines changed

compiler/rustc_parse/src/parser/diagnostics.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -791,13 +791,28 @@ impl<'a> Parser<'a> {
791791
&& let [segment] = &attr_kind.item.path.segments[..]
792792
&& segment.ident.name == sym::cfg
793793
&& let Some(args_span) = attr_kind.item.args.span()
794-
&& let Ok(next_attr) = snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
794+
&& let next_attr = match snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
795+
{
796+
Ok(next_attr) => next_attr,
797+
Err(inner_err) => {
798+
err.cancel();
799+
inner_err.cancel();
800+
return;
801+
}
802+
}
795803
&& let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
796804
&& let Some(next_attr_args_span) = next_attr_kind.item.args.span()
797805
&& let [next_segment] = &next_attr_kind.item.path.segments[..]
798806
&& segment.ident.name == sym::cfg
799-
&& let Ok(next_expr) = snapshot.parse_expr()
800807
{
808+
let next_expr = match snapshot.parse_expr() {
809+
Ok(next_expr) => next_expr,
810+
Err(inner_err) => {
811+
err.cancel();
812+
inner_err.cancel();
813+
return;
814+
}
815+
};
801816
// We have for sure
802817
// #[cfg(..)]
803818
// expr
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>() //~ ERROR expected `;`, found `#`
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,27 @@
1+
error: expected `;`, found `#`
2+
--> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:4:47
3+
|
4+
LL | #[cfg(feature = )]
5+
| ------------------ only `;` terminated statements or tail expressions are allowed after this attribute
6+
LL | [1, 2, 3].iter().map().collect::<String>()
7+
| ^ expected `;` here
8+
LL | #[attr]
9+
| - unexpected token
10+
|
11+
help: add `;` here
12+
|
13+
LL | [1, 2, 3].iter().map().collect::<String>();
14+
| +
15+
help: alternatively, consider surrounding the expression with a block
16+
|
17+
LL | { [1, 2, 3].iter().map().collect::<String>() }
18+
| + +
19+
20+
error: expected statement after outer attribute
21+
--> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
22+
|
23+
LL | #[attr]
24+
| ^^^^^^^
25+
26+
error: aborting due to 2 previous errors
27+

0 commit comments

Comments
 (0)