Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggest adding mut or const after &raw #135751

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 2 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ parse_suffixed_literal_in_attribute = suffixed literals are not allowed in attri

parse_sugg_add_let_for_stmt = you might have meant to introduce a new binding

parse_sugg_add_mut_or_const_in_raw_ref = you might have meant to use a raw reference

parse_sugg_add_semi = add `;` here
parse_sugg_change_inner_attr_to_outer = to annotate the {$item}, change the attribute from inner to outer style

Expand Down
16 changes: 16 additions & 0 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1303,6 +1303,22 @@ impl<'a> Parser<'a> {
Err(e)
}

/// When writing `&raw` that is missing the following `mut` or `const`, we will
/// encounter a parse error when encountering the next expression.
pub(super) fn suggest_add_mut_or_const_in_raw_ref(&mut self, e: &mut Diag<'_>, expr: &P<Expr>) {
if let ExprKind::AddrOf(ast::BorrowKind::Ref, ast::Mutability::Not, r) = &expr.kind
&& let ast::ExprKind::Path(_, p) = &r.kind
&& *p == Symbol::intern("raw")
{
e.span_suggestions(
expr.span.shrink_to_hi(),
fluent::parse_sugg_add_mut_or_const_in_raw_ref,
[" mut".to_string(), " const".to_string()],
Applicability::HasPlaceholders,
);
}
}

/// Suggest add the missing `let` before the identifier in stmt
/// `a: Ty = 1` -> `let a: Ty = 1`
pub(super) fn suggest_add_missing_let_for_stmt(&mut self, err: &mut Diag<'a>) {
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,10 @@ impl<'a> Parser<'a> {
ExprKind::Array(exprs)
} else {
// Vector with one element
self.expect(close)?;
self.expect(close).map_err(|mut e| {
self.suggest_add_mut_or_const_in_raw_ref(&mut e, &first_expr);
e
})?;
ExprKind::Array(thin_vec![first_expr])
}
};
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_parse/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,7 @@ impl<'a> Parser<'a> {
res?
} else {
res.unwrap_or_else(|mut e| {
self.suggest_add_mut_or_const_in_raw_ref(&mut e, expr);
self.recover_missing_dot(&mut e);
let guar = e.emit();
self.recover_stmt();
Expand All @@ -920,6 +921,7 @@ impl<'a> Parser<'a> {
LocalKind::Init(expr) | LocalKind::InitElse(expr, _) => {
self.check_mistyped_turbofish_with_multiple_type_params(e, expr).map_err(
|mut e| {
self.suggest_add_mut_or_const_in_raw_ref(&mut e, expr);
self.recover_missing_dot(&mut e);
e
},
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/raw-ref-op/missing-modifier/let-stmt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! Check that `&raw` that isn't followed by `const` or `mut` produces a
//! helpful error message.
//!
//! Related issue: <https://github.com/rust-lang/rust/issues/133231>.

fn main() {
let foo = 2;
let _ = &raw foo;
//~^ ERROR expected one of
//~| HELP you might have meant to use a raw reference
//~| HELP you might have meant to write a field access
}
19 changes: 19 additions & 0 deletions tests/ui/raw-ref-op/missing-modifier/let-stmt.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error: expected one of `!`, `.`, `::`, `;`, `?`, `else`, `{`, or an operator, found `foo`
--> $DIR/let-stmt.rs:8:18
|
LL | let _ = &raw foo;
| ^^^ expected one of 8 possible tokens
|
help: you might have meant to use a raw reference
|
LL | let _ = &raw mut foo;
| +++
LL | let _ = &raw const foo;
| +++++
help: you might have meant to write a field access
|
LL | let _ = &raw.foo;
| +

error: aborting due to 1 previous error

14 changes: 14 additions & 0 deletions tests/ui/raw-ref-op/missing-modifier/nested-array-expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//! Check that `&raw` that isn't followed by `const` or `mut` produces a
//! helpful error message.
//!
//! Related issue: <https://github.com/rust-lang/rust/issues/133231>.
mod foo {
pub static A: i32 = 0;
}

fn main() {
[&raw foo::A; 3];
//~^ ERROR expected one of
//~| HELP you might have meant to use a raw reference
}
15 changes: 15 additions & 0 deletions tests/ui/raw-ref-op/missing-modifier/nested-array-expr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: expected one of `!`, `,`, `.`, `::`, `;`, `?`, `]`, `{`, or an operator, found `foo`
--> $DIR/nested-array-expr.rs:11:11
|
LL | [&raw foo::A; 3];
| ^^^ expected one of 9 possible tokens
|
help: you might have meant to use a raw reference
|
LL | [&raw mut foo::A; 3];
| +++
LL | [&raw const foo::A; 3];
| +++++

error: aborting due to 1 previous error

16 changes: 16 additions & 0 deletions tests/ui/raw-ref-op/missing-modifier/return-expr.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//! Check that `&raw` that isn't followed by `const` or `mut` produces a
//! helpful error message.
//!
//! Related issue: <https://github.com/rust-lang/rust/issues/133231>.
mod foo {
pub static A: i32 = 0;
}

fn get_ref() -> *const i32 {
&raw foo::A
//~^ ERROR expected one of
//~| HELP you might have meant to use a raw reference
}

fn main() {}
15 changes: 15 additions & 0 deletions tests/ui/raw-ref-op/missing-modifier/return-expr.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `foo`
--> $DIR/return-expr.rs:11:10
|
LL | &raw foo::A
| ^^^ expected one of 8 possible tokens
|
help: you might have meant to use a raw reference
|
LL | &raw mut foo::A
| +++
LL | &raw const foo::A
| +++++

error: aborting due to 1 previous error

Loading