Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_ast/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,10 @@ impl Token {
}
}

pub fn is_range_seperator(&self) -> bool {
Comment thread
RedDocMD marked this conversation as resolved.
Outdated
[DotDot, DotDotDot, DotDotEq].contains(&self.kind)
}

pub fn is_op(&self) -> bool {
match self.kind {
Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_)
Expand Down
10 changes: 7 additions & 3 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ impl<'a> Parser<'a> {
LhsExpr::AttributesParsed(attrs) => Some(attrs),
_ => None,
};
if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind) {
if self.token.is_range_seperator() {
return self.parse_prefix_range_expr(attrs);
} else {
self.parse_prefix_expr(attrs)?
Expand Down Expand Up @@ -512,7 +512,7 @@ impl<'a> Parser<'a> {
}

debug_assert!(
[token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind),
self.token.is_range_seperator(),
"parse_prefix_range_expr: token {:?} is not DotDot/DotDotEq",
self.token
);
Expand Down Expand Up @@ -896,7 +896,11 @@ 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 expr = self.parse_prefix_expr(None);
let expr = if self.token.is_range_seperator() {
self.parse_prefix_range_expr(None)
} else {
self.parse_prefix_expr(None)
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My immediate expectation would be that parse_prefix_expr includes parse_prefix_range_expr. Are there any cases where we use parse_prefix_expr and we want prefix range expressions to be an error? If yes, make sure there's a test for that; if no, then it's probably better to move the range separator check/parse inside parse_prefix_expr.

I've not looked at this code much, but the reason it might matter is for other operator precedence reasons; e.g. what's the correct result of parsing +..1 or 1+..1.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this separation of prefix range parsing from other prefix expr parsing is done to prevent expressions such as -..1 or !..1 from being parsed. Other unary operators can be stacked (may not be typeable), but you cannot have .. or ..= after a unary operator.

let (hi, expr) = self.interpolated_or_expr_span(expr)?;
let span = lo.to(hi);
if let Some(lt) = lifetime {
Expand Down
8 changes: 8 additions & 0 deletions src/test/ui/parser/issue-105634.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// run-pass
Comment thread
RedDocMD marked this conversation as resolved.
Outdated

fn main() {
let _a = ..;
let _b = ..=10;
let _c = &..;
let _d = &..=10;
}