Skip to content

Commit 4efa98c

Browse files
authoredDec 14, 2024··
Rollup merge of #134274 - fmease:amp-raw-is-a-normal-borrow, r=Noratrieb
Add check-pass test for `&raw` `&raw` denotes a normal/non-raw borrow of the path `raw`, not the start of raw borrow since it's not followed by either `const` or `mut`. Ensure this (and variants) will never regress! When I saw the open diagnostic issue #133231 (better parse error (recovery) on `&raw <expr>`), it made me think that we have to make sure that we will never commit too early/overzealously(†) when encountering the sequence `&raw`, even during parse error recovery! Modifying the parser to eagerly treat `&raw` as the start of a raw borrow expr only lead to a single UI test failing, namely [tests/ui/enum-discriminant/ptr_niche.rs](https://github.com/rust-lang/rust/blob/4847d6a9d07d4be9ba3196f6ad444af2d7bdde72/tests/ui/enum-discriminant/ptr_niche.rs). However, this is just coincidental — it didn't *intentionally* test this edge case of the grammar. --- †: With "eager" I mean something like: ```patch diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0904a42d8a4..68d690fd602 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs `@@` -873,11 +873,16 `@@` fn error_remove_borrow_lifetime(&self, span: Span, lt_span: Span) { /// Parse `mut?` or `raw [ const | mut ]`. fn parse_borrow_modifiers(&mut self) -> (ast::BorrowKind, ast::Mutability) { - if self.check_keyword(kw::Raw) && self.look_ahead(1, Token::is_mutability) { + if self.eat_keyword(kw::Raw) { // `raw [ const | mut ]`. - let found_raw = self.eat_keyword(kw::Raw); - assert!(found_raw); - let mutability = self.parse_const_or_mut().unwrap(); + let mutability = self.parse_const_or_mut().unwrap_or_else(|| { + let span = self.prev_token.span; + self.dcx().emit_err(ExpectedMutOrConstInRawBorrowExpr { + span, + after_ampersand: span.shrink_to_hi(), + }); + ast::Mutability::Not + }); (ast::BorrowKind::Raw, mutability) } else { // `mut?` ``` --- r? compiler
2 parents 155dede + f1d2a6a commit 4efa98c

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed
 
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//! The token sequence `&raw` *only* starts a raw borrow expr if it's immediately
2+
//! followed by either `const` or `mut`. If that's not the case, the `&` denotes
3+
//! the start of a normal borrow expr where `raw` is interpreted as a regular
4+
//! identifier and thus denotes the start of a path expr.
5+
//!
6+
//! This test ensures that we never commit too early/overzealously in the parser
7+
//! when encountering the sequence `&raw` (even during parse error recovery) so
8+
//! as not to regress preexisting code.
9+
10+
//@ check-pass
11+
12+
fn main() { // the odd formatting in here is intentional
13+
let raw = 0;
14+
let _ = &raw;
15+
16+
let raw = 0;
17+
let local = 1;
18+
let _: i32 = &raw *local;
19+
20+
let raw = |_| ();
21+
let local = [0];
22+
let () = &raw (local[0]);
23+
}
24+
25+
macro_rules! check {
26+
($e:expr) => { compile_error!("expr"); };
27+
(&raw $e:expr) => {};
28+
}
29+
30+
check!(&raw local);

0 commit comments

Comments
 (0)
Please sign in to comment.