From: Jan Verbeek Date: Sat, 17 Oct 2020 11:36:59 +0000 (+0200) Subject: Suggest correct place to add `self` parameter when inside closure X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=e701ae376a040d9f5614cda3be6fabffe884b432;p=rust.git Suggest correct place to add `self` parameter when inside closure It would incorrectly suggest adding it as a parameter to the closure instead of the containing function. --- diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 219517b4ab2..7517ab66170 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -369,7 +369,7 @@ struct DiagnosticMetadata<'ast> { /// param. currently_processing_generics: bool, - /// The current enclosing function (used for better errors). + /// The current enclosing (non-closure) function (used for better errors). current_function: Option<(FnKind<'ast>, Span)>, /// A list of labels as of yet unused. Labels will be removed from this map when @@ -515,8 +515,10 @@ fn visit_fn(&mut self, fn_kind: FnKind<'ast>, sp: Span, _: NodeId) { FnKind::Fn(FnCtxt::Assoc(_), ..) => NormalRibKind, FnKind::Closure(..) => ClosureOrAsyncRibKind, }; - let previous_value = - replace(&mut self.diagnostic_metadata.current_function, Some((fn_kind, sp))); + let previous_value = self.diagnostic_metadata.current_function; + if matches!(fn_kind, FnKind::Fn(..)) { + self.diagnostic_metadata.current_function = Some((fn_kind, sp)); + } debug!("(resolving function) entering function"); let declaration = fn_kind.decl(); diff --git a/src/test/ui/error-codes/E0424.rs b/src/test/ui/error-codes/E0424.rs index fa0c86ecf48..6e531942cad 100644 --- a/src/test/ui/error-codes/E0424.rs +++ b/src/test/ui/error-codes/E0424.rs @@ -10,6 +10,10 @@ fn foo() { fn baz(_: i32) { self.bar(); //~ ERROR E0424 } + + fn qux() { + let _ = || self.bar(); //~ ERROR E0424 + } } fn main () { diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr index 9b8a29e8272..20b7a4cb6ec 100644 --- a/src/test/ui/error-codes/E0424.stderr +++ b/src/test/ui/error-codes/E0424.stderr @@ -24,14 +24,27 @@ help: add a `self` receiver parameter to make the associated `fn` a method LL | fn baz(&self, _: i32) { | ^^^^^^ +error[E0424]: expected value, found module `self` + --> $DIR/E0424.rs:15:20 + | +LL | fn qux() { + | --- this function doesn't have a `self` parameter +LL | let _ = || self.bar(); + | ^^^^ `self` value is a keyword only available in methods with a `self` parameter + | +help: add a `self` receiver parameter to make the associated `fn` a method + | +LL | fn qux(&self) { + | ^^^^^ + error[E0424]: expected unit struct, unit variant or constant, found module `self` - --> $DIR/E0424.rs:16:9 + --> $DIR/E0424.rs:20:9 | LL | fn main () { | ---- this function can't have a `self` parameter LL | let self = "self"; | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0424`. diff --git a/src/test/ui/issues/issue-5099.rs b/src/test/ui/issues/issue-5099.rs index ee134835c37..b5abccb4b19 100644 --- a/src/test/ui/issues/issue-5099.rs +++ b/src/test/ui/issues/issue-5099.rs @@ -5,6 +5,9 @@ fn a() -> A { fn b(x: i32) { this.b(x); //~ ERROR cannot find value `this` in this scope } + fn c() { + let _ = || this.a; //~ 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 b52fd28b2b5..b39c4a9f272 100644 --- a/src/test/ui/issues/issue-5099.stderr +++ b/src/test/ui/issues/issue-5099.stderr @@ -28,6 +28,21 @@ help: if you meant to use `self`, you are also missing a `self` receiver argumen LL | fn b(&self, x: i32) { | ^^^^^^ -error: aborting due to 2 previous errors +error[E0425]: cannot find value `this` in this scope + --> $DIR/issue-5099.rs:9:20 + | +LL | let _ = || this.a; + | ^^^^ not found in this scope + | +help: you might have meant to use `self` here instead + | +LL | let _ = || self.a; + | ^^^^ +help: if you meant to use `self`, you are also missing a `self` receiver argument + | +LL | fn c(&self) { + | ^^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0425`.