Improve handling of expr->field errors
The current message for "`->` used for field access" is the following: ```rust error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `->` --> src/main.rs:2:6 | 2 | a->b; | ^^ expected one of 8 possible tokens ``` (playground link[1]) This PR tries to address this by adding a dedicated error message and recovery. The proposed error message is: ``` error: `->` used for field access or method call --> ./tiny_test.rs:2:6 | 2 | a->b; | ^^ help: try using `.` instead | = help: the `.` operator will dereference the value if needed ``` (feel free to bikeshed it as much as necessary) [1]: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=7f8b6f4433aa7866124123575456f54e Signed-off-by: Sasha Pourcelot <sasha.pourcelot@protonmail.com>
This commit is contained in:
parent
a61b14d15e
commit
98332c108b
@ -230,6 +230,10 @@ parse_expected_struct_field = expected one of `,`, `:`, or `{"}"}`, found `{$tok
|
||||
|
||||
parse_expected_trait_in_trait_impl_found_type = expected a trait, found type
|
||||
|
||||
parse_expr_rarrow_call = `->` used for field access or method call
|
||||
.suggestion = try using `.` instead
|
||||
.help = the `.` operator will dereference the value if needed
|
||||
|
||||
parse_extern_crate_name_with_dashes = crate name using dashes are not valid in `extern crate` statements
|
||||
.label = dash-separated idents are not valid
|
||||
.suggestion = if the original crate name uses dashes you need to use underscores in the code
|
||||
|
@ -2988,3 +2988,12 @@ pub(crate) struct AsyncImpl {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(parse_expr_rarrow_call)]
|
||||
#[help]
|
||||
pub(crate) struct ExprRArrowCall {
|
||||
#[primary_span]
|
||||
#[suggestion(style = "short", applicability = "machine-applicable", code = ".")]
|
||||
pub span: Span,
|
||||
}
|
||||
|
@ -979,6 +979,12 @@ fn parse_expr_dot_or_call_with_(&mut self, mut e: P<Expr>, lo: Span) -> PResult<
|
||||
// we are using noexpect here because we don't expect a `.` directly after a `return`
|
||||
// which could be suggested otherwise
|
||||
self.eat_noexpect(&token::Dot)
|
||||
} else if self.token.kind == TokenKind::RArrow && self.may_recover() {
|
||||
// Recovery for `expr->suffix`.
|
||||
self.bump();
|
||||
let span = self.prev_token.span;
|
||||
self.dcx().emit_err(errors::ExprRArrowCall { span });
|
||||
true
|
||||
} else {
|
||||
self.eat(&token::Dot)
|
||||
};
|
||||
|
33
tests/ui/parser/expr-rarrow-call.fixed
Normal file
33
tests/ui/parser/expr-rarrow-call.fixed
Normal file
@ -0,0 +1,33 @@
|
||||
//@ run-rustfix
|
||||
#![allow(
|
||||
dead_code,
|
||||
unused_must_use
|
||||
)]
|
||||
|
||||
struct Named {
|
||||
foo: usize
|
||||
}
|
||||
|
||||
struct Unnamed(usize);
|
||||
|
||||
fn named_struct_field_access(named: &Named) {
|
||||
named.foo; //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
fn unnamed_struct_field_access(unnamed: &Unnamed) {
|
||||
unnamed.0; //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
fn tuple_field_access(t: &(u8, u8)) {
|
||||
t.0; //~ ERROR `->` used for field access or method call
|
||||
t.1; //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Foo;
|
||||
|
||||
fn method_call(foo: &Foo) {
|
||||
foo.clone(); //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
fn main() {}
|
33
tests/ui/parser/expr-rarrow-call.rs
Normal file
33
tests/ui/parser/expr-rarrow-call.rs
Normal file
@ -0,0 +1,33 @@
|
||||
//@ run-rustfix
|
||||
#![allow(
|
||||
dead_code,
|
||||
unused_must_use
|
||||
)]
|
||||
|
||||
struct Named {
|
||||
foo: usize
|
||||
}
|
||||
|
||||
struct Unnamed(usize);
|
||||
|
||||
fn named_struct_field_access(named: &Named) {
|
||||
named->foo; //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
fn unnamed_struct_field_access(unnamed: &Unnamed) {
|
||||
unnamed->0; //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
fn tuple_field_access(t: &(u8, u8)) {
|
||||
t->0; //~ ERROR `->` used for field access or method call
|
||||
t->1; //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Foo;
|
||||
|
||||
fn method_call(foo: &Foo) {
|
||||
foo->clone(); //~ ERROR `->` used for field access or method call
|
||||
}
|
||||
|
||||
fn main() {}
|
42
tests/ui/parser/expr-rarrow-call.stderr
Normal file
42
tests/ui/parser/expr-rarrow-call.stderr
Normal file
@ -0,0 +1,42 @@
|
||||
error: `->` used for field access or method call
|
||||
--> $DIR/expr-rarrow-call.rs:14:10
|
||||
|
|
||||
LL | named->foo;
|
||||
| ^^ help: try using `.` instead
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
|
||||
error: `->` used for field access or method call
|
||||
--> $DIR/expr-rarrow-call.rs:18:12
|
||||
|
|
||||
LL | unnamed->0;
|
||||
| ^^ help: try using `.` instead
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
|
||||
error: `->` used for field access or method call
|
||||
--> $DIR/expr-rarrow-call.rs:22:6
|
||||
|
|
||||
LL | t->0;
|
||||
| ^^ help: try using `.` instead
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
|
||||
error: `->` used for field access or method call
|
||||
--> $DIR/expr-rarrow-call.rs:23:6
|
||||
|
|
||||
LL | t->1;
|
||||
| ^^ help: try using `.` instead
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
|
||||
error: `->` used for field access or method call
|
||||
--> $DIR/expr-rarrow-call.rs:30:8
|
||||
|
|
||||
LL | foo->clone();
|
||||
| ^^ help: try using `.` instead
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
@ -3,8 +3,9 @@ fn bar() -> String {
|
||||
[1, 2, 3].iter() //~ ERROR expected `;`, found `#`
|
||||
#[feature]
|
||||
attr::fn bar() -> String { //~ ERROR expected identifier, found keyword `fn`
|
||||
//~^ ERROR expected one of `.`, `;`, `?`, `}`, or an operator, found `->`
|
||||
//~^ ERROR expected one of `(`, `.`, `::`, `;`, `?`, `}`, or an operator, found `{`
|
||||
//~| ERROR expected `;`, found `bar`
|
||||
//~| ERROR `->` used for field access or method call
|
||||
#[attr]
|
||||
[1, 2, 3].iter().map().collect::<String>()
|
||||
#[attr]
|
||||
|
@ -33,11 +33,19 @@ LL | attr::fn bar() -> String {
|
||||
| |
|
||||
| help: add `;` here
|
||||
|
||||
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `->`
|
||||
error: `->` used for field access or method call
|
||||
--> $DIR/issue-118530-ice.rs:5:20
|
||||
|
|
||||
LL | attr::fn bar() -> String {
|
||||
| ^^ expected one of `.`, `;`, `?`, `}`, or an operator
|
||||
| ^^ help: try using `.` instead
|
||||
|
|
||||
= help: the `.` operator will dereference the value if needed
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: expected one of `(`, `.`, `::`, `;`, `?`, `}`, or an operator, found `{`
|
||||
--> $DIR/issue-118530-ice.rs:5:30
|
||||
|
|
||||
LL | attr::fn bar() -> String {
|
||||
| ^ expected one of 7 possible tokens
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user