diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index c57c0e5194185..ce154bb09f450 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -7,6 +7,7 @@ use crate::{PathResult, PathSource, Segment}; use rustc_ast::ast::{self, Expr, ExprKind, Item, ItemKind, NodeId, Path, Ty, TyKind}; use rustc_ast::util::lev_distance::find_best_match_for_name; +use rustc_ast::visit::FnKind; use rustc_data_structures::fx::FxHashSet; use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticBuilder}; use rustc_hir as hir; @@ -175,15 +176,38 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> { let mut err = self.r.session.struct_span_err_with_code(base_span, &base_msg, code); // Emit help message for fake-self from other languages (e.g., `this` in Javascript). - if ["this", "my"].contains(&&*item_str.as_str()) - && self.self_value_is_available(path[0].ident.span, span) - { + if ["this", "my"].contains(&&*item_str.as_str()) && self.self_type_is_available(span) { err.span_suggestion_short( span, "you might have meant to use `self` here instead", "self".to_string(), Applicability::MaybeIncorrect, ); + if !self.self_value_is_available(path[0].ident.span, span) { + if let Some((FnKind::Fn(_, _, sig, ..), fn_span)) = + &self.diagnostic_metadata.current_function + { + if let Some(param) = sig.decl.inputs.get(0) { + err.span_suggestion_verbose( + param.span.shrink_to_lo(), + "you are also missing a `self` receiver argument", + "&self, ".to_string(), + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_verbose( + self.r + .session + .source_map() + .span_through_char(*fn_span, '(') + .shrink_to_hi(), + "you are also missing a `self` receiver argument", + "&self".to_string(), + Applicability::MaybeIncorrect, + ); + } + } + } } // Emit special messages for unresolved `Self` and `self`. diff --git a/src/test/ui/issues/issue-5099.rs b/src/test/ui/issues/issue-5099.rs index d00fff3280920..ee134835c37ed 100644 --- a/src/test/ui/issues/issue-5099.rs +++ b/src/test/ui/issues/issue-5099.rs @@ -1,3 +1,10 @@ -trait B < A > { fn a() -> A { this.a } } //~ ERROR cannot find value `this` in this scope +trait B { + fn a() -> A { + this.a //~ ERROR cannot find value `this` in this scope + } + fn b(x: i32) { + this.b(x); //~ ERROR cannot find value `this` in this scope + } +} fn main() {} diff --git a/src/test/ui/issues/issue-5099.stderr b/src/test/ui/issues/issue-5099.stderr index cc11db9c5eca6..56b02c45a08d7 100644 --- a/src/test/ui/issues/issue-5099.stderr +++ b/src/test/ui/issues/issue-5099.stderr @@ -1,9 +1,33 @@ error[E0425]: cannot find value `this` in this scope - --> $DIR/issue-5099.rs:1:31 + --> $DIR/issue-5099.rs:3:9 | -LL | trait B < A > { fn a() -> A { this.a } } - | ^^^^ not found in this scope +LL | this.a + | ^^^^ not found in this scope + | +help: you might have meant to use `self` here instead + | +LL | self.a + | ^^^^ +help: you are also missing a `self` receiver argument + | +LL | fn a(&self) -> A { + | ^^^^^ + +error[E0425]: cannot find value `this` in this scope + --> $DIR/issue-5099.rs:6:9 + | +LL | this.b(x); + | ^^^^ not found in this scope + | +help: you might have meant to use `self` here instead + | +LL | self.b(x); + | ^^^^ +help: you are also missing a `self` receiver argument + | +LL | fn b(&self, x: i32) { + | ^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0425`.