From d00c7e78ea9e887e7e7d04dbe6c233444f4e6295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 23 Sep 2023 17:23:16 +0000 Subject: [PATCH] Point at field definition when unresolved name exists in `Self` --- compiler/rustc_resolve/src/late/diagnostics.rs | 14 +++++++------- ...thod-in-self-not-available-in-assoc-fn.stderr | 10 ++++++++-- tests/ui/resolve/issue-2356.stderr | 10 ++++++++-- tests/ui/resolve/issue-60057.stderr | 5 ++++- ...able-with-name-similar-to-struct-field.stderr | 16 ++++++++-------- .../resolve/unresolved_static_type_field.stderr | 5 ++++- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 3ff022b0e21..4ac5d6d19aa 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -41,7 +41,7 @@ type Res = def::Res; /// A field or associated item from self type suggested in case of resolution failure. enum AssocSuggestion { - Field, + Field(Span), MethodWithSelf { called: bool }, AssocFn { called: bool }, AssocType, @@ -51,7 +51,7 @@ enum AssocSuggestion { impl AssocSuggestion { fn action(&self) -> &'static str { match self { - AssocSuggestion::Field => "use the available field", + AssocSuggestion::Field(_) => "use the available field", AssocSuggestion::MethodWithSelf { called: true } => { "call the method with the fully-qualified path" } @@ -670,7 +670,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { _ => String::new(), }; match candidate { - AssocSuggestion::Field => { + AssocSuggestion::Field(field_span) => { if self_is_available { err.span_suggestion_verbose( span.shrink_to_lo(), @@ -679,7 +679,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { Applicability::MachineApplicable, ); } else { - err.span_label(span, "a field by this name exists in `Self`"); + err.span_label(field_span, "a field by that name exists in `Self`"); } } AssocSuggestion::MethodWithSelf { called } if self_is_available => { @@ -1715,11 +1715,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { resolution.full_res() { if let Some(field_ids) = self.r.field_def_ids(did) { - if field_ids + if let Some(field_id) = field_ids .iter() - .any(|&field_id| ident.name == self.r.tcx.item_name(field_id)) + .find(|&&field_id| ident.name == self.r.tcx.item_name(field_id)) { - return Some(AssocSuggestion::Field); + return Some(AssocSuggestion::Field(self.r.def_span(*field_id))); } } } diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr index 4ced51c6f94..3c44c1c249c 100644 --- a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr +++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr @@ -1,20 +1,26 @@ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9 | +LL | field: u32, + | ---------- a field by that name exists in `Self` +... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here ... LL | field; - | ^^^^^ a field by this name exists in `Self` + | ^^^^^ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15 | +LL | field: u32, + | ---------- a field by that name exists in `Self` +... LL | fn field(&self) -> u32 { | ----- a method by that name is available on `Self` here ... LL | Foo { field } - | ^^^^^ a field by this name exists in `Self` + | ^^^^^ error[E0425]: cannot find value `field` in this scope --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15 diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr index 191754c5dc4..5f75ae98870 100644 --- a/tests/ui/resolve/issue-2356.stderr +++ b/tests/ui/resolve/issue-2356.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:39:5 | +LL | whiskers: isize, + | --------------- a field by that name exists in `Self` +... LL | whiskers -= other; - | ^^^^^^^^ a field by this name exists in `Self` + | ^^^^^^^^ error[E0424]: expected value, found module `self` --> $DIR/issue-2356.rs:65:8 @@ -31,8 +34,11 @@ LL | self.whiskers = 0; error[E0425]: cannot find value `whiskers` in this scope --> $DIR/issue-2356.rs:84:5 | +LL | whiskers: isize, + | --------------- a field by that name exists in `Self` +... LL | whiskers = 4; - | ^^^^^^^^ a field by this name exists in `Self` + | ^^^^^^^^ error[E0424]: expected value, found module `self` --> $DIR/issue-2356.rs:92:5 diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr index 88117ec96d2..a2ab8644353 100644 --- a/tests/ui/resolve/issue-60057.stderr +++ b/tests/ui/resolve/issue-60057.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:8:21 | +LL | banana: u8, + | ---------- a field by that name exists in `Self` +... LL | banana: banana - | ^^^^^^ a field by this name exists in `Self` + | ^^^^^^ error[E0425]: cannot find value `banana` in this scope --> $DIR/issue-60057.rs:14:21 diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr index a77675a1b03..0306c8af87d 100644 --- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr +++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr @@ -1,20 +1,20 @@ error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16 | +LL | config: String, + | -------------- a field by that name exists in `Self` +... LL | Self { config } - | ^^^^^^ - | | - | a field by this name exists in `Self` - | help: a local variable with a similar name exists: `cofig` + | ^^^^^^ help: a local variable with a similar name exists: `cofig` error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20 | +LL | config: String, + | -------------- a field by that name exists in `Self` +... LL | println!("{config}"); - | ^^^^^^ - | | - | a field by this name exists in `Self` - | help: a local variable with a similar name exists: `cofig` + | ^^^^^^ help: a local variable with a similar name exists: `cofig` error[E0425]: cannot find value `config` in this scope --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20 diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr index 06926b53ddd..035dc9b9656 100644 --- a/tests/ui/resolve/unresolved_static_type_field.stderr +++ b/tests/ui/resolve/unresolved_static_type_field.stderr @@ -1,8 +1,11 @@ error[E0425]: cannot find value `cx` in this scope --> $DIR/unresolved_static_type_field.rs:9:11 | +LL | cx: bool, + | -------- a field by that name exists in `Self` +... LL | f(cx); - | ^^ a field by this name exists in `Self` + | ^^ error: aborting due to previous error