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.
This commit is contained in:
parent
e7bbe8ce93
commit
a5d9def321
@ -792,13 +792,28 @@ pub(super) fn attr_on_non_tail_expr(&self, expr: &Expr) {
|
|||||||
&& let [segment] = &attr_kind.item.path.segments[..]
|
&& let [segment] = &attr_kind.item.path.segments[..]
|
||||||
&& segment.ident.name == sym::cfg
|
&& segment.ident.name == sym::cfg
|
||||||
&& let Some(args_span) = attr_kind.item.args.span()
|
&& let Some(args_span) = attr_kind.item.args.span()
|
||||||
&& let Ok(next_attr) = snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
|
&& let next_attr = match snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
|
||||||
|
{
|
||||||
|
Ok(next_attr) => next_attr,
|
||||||
|
Err(inner_err) => {
|
||||||
|
err.cancel();
|
||||||
|
inner_err.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
&& let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
|
&& let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
|
||||||
&& let Some(next_attr_args_span) = next_attr_kind.item.args.span()
|
&& let Some(next_attr_args_span) = next_attr_kind.item.args.span()
|
||||||
&& let [next_segment] = &next_attr_kind.item.path.segments[..]
|
&& let [next_segment] = &next_attr_kind.item.path.segments[..]
|
||||||
&& segment.ident.name == sym::cfg
|
&& segment.ident.name == sym::cfg
|
||||||
&& let Ok(next_expr) = snapshot.parse_expr()
|
|
||||||
{
|
{
|
||||||
|
let next_expr = match snapshot.parse_expr() {
|
||||||
|
Ok(next_expr) => next_expr,
|
||||||
|
Err(inner_err) => {
|
||||||
|
err.cancel();
|
||||||
|
inner_err.cancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
// We have for sure
|
// We have for sure
|
||||||
// #[cfg(..)]
|
// #[cfg(..)]
|
||||||
// expr
|
// expr
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
// Issue #118164: recovery path leaving unemitted error behind
|
||||||
|
fn bar() -> String {
|
||||||
|
#[cfg(feature = )]
|
||||||
|
[1, 2, 3].iter().map().collect::<String>() //~ ERROR expected `;`, found `#`
|
||||||
|
#[attr] //~ ERROR expected statement after outer attribute
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let _ = bar();
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
error: expected `;`, found `#`
|
||||||
|
--> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:4:47
|
||||||
|
|
|
||||||
|
LL | #[cfg(feature = )]
|
||||||
|
| ------------------ only `;` terminated statements or tail expressions are allowed after this attribute
|
||||||
|
LL | [1, 2, 3].iter().map().collect::<String>()
|
||||||
|
| ^ expected `;` here
|
||||||
|
LL | #[attr]
|
||||||
|
| - unexpected token
|
||||||
|
|
|
||||||
|
help: add `;` here
|
||||||
|
|
|
||||||
|
LL | [1, 2, 3].iter().map().collect::<String>();
|
||||||
|
| +
|
||||||
|
help: alternatively, consider surrounding the expression with a block
|
||||||
|
|
|
||||||
|
LL | { [1, 2, 3].iter().map().collect::<String>() }
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: expected statement after outer attribute
|
||||||
|
--> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
|
||||||
|
|
|
||||||
|
LL | #[attr]
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user