Skip to content

Commit

Permalink
Fix parser ICE from attrs
Browse files Browse the repository at this point in the history
  • Loading branch information
chenyukang committed Dec 2, 2023
1 parent df0295f commit 5ff428c
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 12 deletions.
16 changes: 4 additions & 12 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ use crate::errors::{
TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
};

use crate::fluent_generated as fluent;
use crate::parser;
use crate::parser::attr::InnerAttrPolicy;
Expand Down Expand Up @@ -772,8 +771,10 @@ impl<'a> Parser<'a> {
&& let ast::AttrKind::Normal(attr_kind) = &attr.kind
&& let [segment] = &attr_kind.item.path.segments[..]
&& segment.ident.name == sym::cfg
&& let Some(args_span) = attr_kind.item.args.span()
&& let Ok(next_attr) = snapshot.parse_attribute(InnerAttrPolicy::Forbidden(None))
&& let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
&& let Some(next_attr_args_span) = next_attr_kind.item.args.span()
&& let [next_segment] = &next_attr_kind.item.path.segments[..]
&& segment.ident.name == sym::cfg
&& let Ok(next_expr) = snapshot.parse_expr()
Expand All @@ -787,23 +788,14 @@ impl<'a> Parser<'a> {
let margin = self.sess.source_map().span_to_margin(next_expr.span).unwrap_or(0);
let sugg = vec![
(attr.span.with_hi(segment.span().hi()), "if cfg!".to_string()),
(
attr_kind.item.args.span().unwrap().shrink_to_hi().with_hi(attr.span.hi()),
" {".to_string(),
),
(args_span.shrink_to_hi().with_hi(attr.span.hi()), " {".to_string()),
(expr.span.shrink_to_lo(), " ".to_string()),
(
next_attr.span.with_hi(next_segment.span().hi()),
"} else if cfg!".to_string(),
),
(
next_attr_kind
.item
.args
.span()
.unwrap()
.shrink_to_hi()
.with_hi(next_attr.span.hi()),
next_attr_args_span.shrink_to_hi().with_hi(next_attr.span.hi()),
" {".to_string(),
),
(next_expr.span.shrink_to_lo(), " ".to_string()),
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/parser/issues/issue-118530-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
fn bar() -> String {
#[cfg]
[1, 2, 3].iter() //~ ERROR expected `;`, found `#`
#[feature]
attr::fn bar() -> String { //~ ERROR expected identifier, found keyword `fn`
//~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `->`
//~| ERROR expected `;`, found `bar`
#[attr]
[1, 2, 3].iter().map().collect::<String>()
#[attr]

}()
}

fn main() { }
43 changes: 43 additions & 0 deletions tests/ui/parser/issues/issue-118530-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
error: expected `;`, found `#`
--> $DIR/issue-118530-ice.rs:3:21
|
LL | #[cfg]
| ------ only `;` terminated statements or tail expressions are allowed after this attribute
LL | [1, 2, 3].iter()
| ^ expected `;` here
LL | #[feature]
| - unexpected token
|
help: add `;` here
|
LL | [1, 2, 3].iter();
| +
help: alternatively, consider surrounding the expression with a block
|
LL | { [1, 2, 3].iter() }
| + +

error: expected identifier, found keyword `fn`
--> $DIR/issue-118530-ice.rs:5:11
|
LL | attr::fn bar() -> String {
| ^^ expected identifier, found keyword

error: expected `;`, found `bar`
--> $DIR/issue-118530-ice.rs:5:13
|
LL | #[feature]
| ---------- only `;` terminated statements or tail expressions are allowed after this attribute
LL | attr::fn bar() -> String {
| ^--- unexpected token
| |
| help: add `;` here

error: expected one of `.`, `;`, `?`, `}`, or an operator, found `->`
--> $DIR/issue-118530-ice.rs:5:20
|
LL | attr::fn bar() -> String {
| ^^ expected one of `.`, `;`, `?`, `}`, or an operator

error: aborting due to 4 previous errors

10 changes: 10 additions & 0 deletions tests/ui/parser/issues/issue-118531-ice.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
fn bar() -> String {
#[cfg(feature = )]
[1, 2, 3].iter().map().collect::<String>() //~ ERROR expected `;`, found `#`

#[attr] //~ ERROR attributes on expressions are experimental [E0658]
//~^ ERROR cannot find attribute `attr` in this scope
String::new()
}

fn main() { }
38 changes: 38 additions & 0 deletions tests/ui/parser/issues/issue-118531-ice.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
error: expected `;`, found `#`
--> $DIR/issue-118531-ice.rs:3: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 |
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[E0658]: attributes on expressions are experimental
--> $DIR/issue-118531-ice.rs:5:5
|
LL | #[attr]
| ^^^^^^^
|
= note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information
= help: add `#![feature(stmt_expr_attributes)]` to the crate attributes to enable

error: cannot find attribute `attr` in this scope
--> $DIR/issue-118531-ice.rs:5:7
|
LL | #[attr]
| ^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0658`.

0 comments on commit 5ff428c

Please sign in to comment.