Skip to content

Commit aaa220e

Browse files
committed
Move parse_or_use_outer_attributes out of parse_expr_prefix_range.
This eliminates another `Option<AttrWrapper>` argument and changes one obscure error message.
1 parent 802779f commit aaa220e

File tree

5 files changed

+25
-15
lines changed

5 files changed

+25
-15
lines changed

compiler/rustc_parse/messages.ftl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ parse_dot_dot_dot_for_remaining_fields = expected field pattern, found `{$token_
133133
parse_dot_dot_dot_range_to_pattern_not_allowed = range-to patterns with `...` are not allowed
134134
.suggestion = use `..=` instead
135135
136+
parse_dot_dot_range_attribute = attributes are not allowed on range expressions starting with `..`
137+
136138
parse_dotdotdot = unexpected token: `...`
137139
.suggest_exclusive_range = use `..` for an exclusive range
138140
.suggest_inclusive_range = or `..=` for an inclusive range

compiler/rustc_parse/src/errors.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2989,3 +2989,10 @@ pub(crate) struct ExprRArrowCall {
29892989
#[suggestion(style = "short", applicability = "machine-applicable", code = ".")]
29902990
pub span: Span,
29912991
}
2992+
2993+
#[derive(Diagnostic)]
2994+
#[diag(parse_dot_dot_range_attribute)]
2995+
pub(crate) struct DotDotRangeAttribute {
2996+
#[primary_span]
2997+
pub span: Span,
2998+
}

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,10 @@ impl<'a> Parser<'a> {
152152
expr
153153
}
154154
LhsExpr::Unparsed { attrs } => {
155+
let attrs = self.parse_or_use_outer_attributes(attrs)?;
155156
if self.token.is_range_separator() {
156157
return self.parse_expr_prefix_range(attrs);
157158
} else {
158-
let attrs = self.parse_or_use_outer_attributes(attrs)?;
159159
self.parse_expr_prefix(attrs)?
160160
}
161161
}
@@ -499,7 +499,12 @@ impl<'a> Parser<'a> {
499499
}
500500

501501
/// Parses prefix-forms of range notation: `..expr`, `..`, `..=expr`.
502-
fn parse_expr_prefix_range(&mut self, attrs: Option<AttrWrapper>) -> PResult<'a, P<Expr>> {
502+
fn parse_expr_prefix_range(&mut self, attrs: AttrWrapper) -> PResult<'a, P<Expr>> {
503+
if !attrs.is_empty() {
504+
let err = errors::DotDotRangeAttribute { span: self.token.span };
505+
self.dcx().emit_err(err);
506+
}
507+
503508
// Check for deprecated `...` syntax.
504509
if self.token == token::DotDotDot {
505510
self.err_dotdotdot_syntax(self.token.span);
@@ -516,11 +521,7 @@ impl<'a> Parser<'a> {
516521
_ => RangeLimits::Closed,
517522
};
518523
let op = AssocOp::from_token(&self.token);
519-
// FIXME: `parse_prefix_range_expr` is called when the current
520-
// token is `DotDot`, `DotDotDot`, or `DotDotEq`. If we haven't already
521-
// parsed attributes, then trying to parse them here will always fail.
522-
// We should figure out how we want attributes on range expressions to work.
523-
let attrs = self.parse_or_use_outer_attributes(attrs)?;
524+
let attrs = self.parse_outer_attributes()?;
524525
self.collect_tokens_for_expr(attrs, |this, attrs| {
525526
let lo = this.token.span;
526527
let maybe_lt = this.look_ahead(1, |t| t.clone());
@@ -871,10 +872,10 @@ impl<'a> Parser<'a> {
871872
let has_lifetime = self.token.is_lifetime() && self.look_ahead(1, |t| t != &token::Colon);
872873
let lifetime = has_lifetime.then(|| self.expect_lifetime()); // For recovery, see below.
873874
let (borrow_kind, mutbl) = self.parse_borrow_modifiers(lo);
875+
let attrs = self.parse_outer_attributes()?;
874876
let expr = if self.token.is_range_separator() {
875-
self.parse_expr_prefix_range(None)
877+
self.parse_expr_prefix_range(attrs)
876878
} else {
877-
let attrs = self.parse_outer_attributes()?;
878879
self.parse_expr_prefix(attrs)
879880
}?;
880881
let hi = self.interpolated_or_expr_span(&expr);

tests/ui/parser/attribute/attr-stmt-expr-attr-bad.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ fn main() {}
2828
#[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; }
2929
//~^ ERROR an inner attribute is not permitted in this context
3030
#[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; }
31-
//~^ ERROR expected expression, found `..`
31+
//~^ ERROR attributes are not allowed on range expressions starting with `..`
3232
#[cfg(FALSE)] fn e() { let _ = #[attr] ..; }
33-
//~^ ERROR expected expression, found `..`
33+
//~^ ERROR attributes are not allowed on range expressions starting with `..`
3434
#[cfg(FALSE)] fn e() { let _ = #[attr] &#![attr] 0; }
3535
//~^ ERROR an inner attribute is not permitted in this context
3636
#[cfg(FALSE)] fn e() { let _ = #[attr] &mut #![attr] 0; }

tests/ui/parser/attribute/attr-stmt-expr-attr-bad.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,17 +119,17 @@ LL | #[cfg(FALSE)] fn e() { let _ = move || #![attr] {foo}; }
119119
= note: inner attributes, like `#![no_std]`, annotate the item enclosing them, and are usually found at the beginning of source files
120120
= note: outer attributes, like `#[test]`, annotate the item following them
121121

122-
error: expected expression, found `..`
122+
error: attributes are not allowed on range expressions starting with `..`
123123
--> $DIR/attr-stmt-expr-attr-bad.rs:30:40
124124
|
125125
LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..#[attr] 0; }
126-
| ^^ expected expression
126+
| ^^
127127

128-
error: expected expression, found `..`
128+
error: attributes are not allowed on range expressions starting with `..`
129129
--> $DIR/attr-stmt-expr-attr-bad.rs:32:40
130130
|
131131
LL | #[cfg(FALSE)] fn e() { let _ = #[attr] ..; }
132-
| ^^ expected expression
132+
| ^^
133133

134134
error: an inner attribute is not permitted in this context
135135
--> $DIR/attr-stmt-expr-attr-bad.rs:34:41

0 commit comments

Comments
 (0)