diff options
| author | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-06-19 15:37:31 +1000 |
|---|---|---|
| committer | Nicholas Nethercote <n.nethercote@gmail.com> | 2024-06-19 19:12:00 +1000 |
| commit | aaa220e8757d1d2bb3a7b4742db9e289c8454dc2 (patch) | |
| tree | 2eec7d6fe436be5faf45bfe15110d4039c780d0e | |
| parent | 802779f77ddaac18865e5e52e01c5e4d122e9090 (diff) | |
| download | rust-aaa220e8757d1d2bb3a7b4742db9e289c8454dc2.tar.gz rust-aaa220e8757d1d2bb3a7b4742db9e289c8454dc2.zip | |
Move `parse_or_use_outer_attributes` out of `parse_expr_prefix_range`.
This eliminates another `Option<AttrWrapper>` argument and changes one obscure error message.
| -rw-r--r-- | compiler/rustc_parse/messages.ftl | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 7 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 19 | ||||
| -rw-r--r-- | tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs | 4 | ||||
| -rw-r--r-- | tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr | 8 |
5 files changed, 25 insertions, 15 deletions
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl index f678d11213c..efb9526eabc 100644 --- a/compiler/rustc_parse/messages.ftl +++ b/compiler/rustc_parse/messages.ftl @@ -133,6 +133,8 @@ parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `{$token_ parse_dot_dot_dot_range_to_pattern_not_allowed = range-to patterns with `...` are not allowed .suggestion = use `..=` instead +parse_dot_dot_range_attribute = attributes are not allowed on range expressions starting with `..` + parse_dotdotdot = unexpected token: `...` .suggest_exclusive_range = use `..` for an exclusive range .suggest_inclusive_range = or `..=` for an inclusive range diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 6c1fcbe06fc..f0ef1112f9e 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2989,3 +2989,10 @@ pub(crate) struct ExprRArrowCall { #[suggestion(style = "short", applicability = "machine-applicable", code = ".")] pub span: Span, } + +#[derive(Diagnostic)] +#[diag(parse_dot_dot_range_attribute)] +pub(crate) struct DotDotRangeAttribute { + #[primary_span] + pub span: Span, +} diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index e96b97da9fd..ab3f8a5dbeb 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -152,10 +152,10 @@ impl<'a> Parser<'a> { expr } LhsExpr::Unparsed { attrs } => { + let attrs = self.parse_or_use_outer_attributes(attrs)?; if self.token.is_range_separator() { return self.parse_expr_prefix_range(attrs); } else { - let attrs = self.parse_or_use_outer_attributes(attrs)?; self.parse_expr_prefix(attrs)? } } @@ -499,7 +499,12 @@ impl<'a> Parser<'a> { } /// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`. - fn parse_expr_prefix_range(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> { + fn parse_expr_prefix_range(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>> { + if !attrs.is_empty() { + let err = errors::DotDotRangeAttribute { span: self.token.span }; + self.dcx().emit_err(err); + } + // Check for deprecated `...` syntax. if self.token == token::DotDotDot { self.err_dotdotdot_syntax(self.token.span); @@ -516,11 +521,7 @@ impl<'a> Parser<'a> { _ => RangeLimits::Closed, }; let op = AssocOp::from_token(&self.token); - // FIXME: `parse_prefix_range_expr` is called when the current - // token is `DotDot`, `DotDotDot`, or `DotDotEq`. If we haven't already - // parsed attributes, then trying to parse them here will always fail. - // We should figure out how we want attributes on range expressions to work. - let attrs = self.parse_or_use_outer_attributes(attrs)?; + let attrs = self.parse_outer_attributes()?; self.collect_tokens_for_expr(attrs, |this, attrs| { let lo = this.token.span; let maybe_lt = this.look_ahead(1, |t| t.clone()); @@ -871,10 +872,10 @@ impl<'a> Parser<'a> { let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon); let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below. let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo); + let attrs = self.parse_outer_attributes()?; let expr = if self.token.is_range_separator() { - self.parse_expr_prefix_range(None) + self.parse_expr_prefix_range(attrs) } else { - let attrs = self.parse_outer_attributes()?; self.parse_expr_prefix(attrs) }?; let hi = self.interpolated_or_expr_span(&expr); diff --git a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs index d1950087c4c..26761a1d254 100644 --- a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs +++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs @@ -28,9 +28,9 @@ fn main() {} #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } //~^ ERROR an inner attribute is not permitted in this context #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } -//~^ ERROR expected expression, found `..` +//~^ ERROR attributes are not allowed on range expressions starting with `..` #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } -//~^ ERROR expected expression, found `..` +//~^ ERROR attributes are not allowed on range expressions starting with `..` #[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; } //~^ ERROR an inner attribute is not permitted in this context #[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; } diff --git a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr index e46c591080d..3593c5182ce 100644 --- a/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr +++ b/tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr @@ -119,17 +119,17 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; } = note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files = note: outer attributes, like `#[test]`, annotate the item following them -error: expected expression, found `..` +error: attributes are not allowed on range expressions starting with `..` --> $DIR/attr-stmt-expr-attr-bad.rs:30:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; } - | ^^ expected expression + | ^^ -error: expected expression, found `..` +error: attributes are not allowed on range expressions starting with `..` --> $DIR/attr-stmt-expr-attr-bad.rs:32:40 | LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; } - | ^^ expected expression + | ^^ error: an inner attribute is not permitted in this context --> $DIR/attr-stmt-expr-attr-bad.rs:34:41 |
