about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-10-17 20:26:21 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-10-17 20:26:21 -0700
commitf65a492afcd9cd892a1a5591f938efd41b5e0d24 (patch)
tree546101f39f5a3ea68986c042d91f86e3f8fc1eb4
parent11011013f2b609b6cf58c96555b9e31dfd19d7ee (diff)
downloadrust-f65a492afcd9cd892a1a5591f938efd41b5e0d24.tar.gz
rust-f65a492afcd9cd892a1a5591f938efd41b5e0d24.zip
Point at enclosing function without `self` receiver
-rw-r--r--src/librustc_resolve/late.rs8
-rw-r--r--src/librustc_resolve/late/diagnostics.rs3
-rw-r--r--src/test/ui/error-codes/E0424.stderr14
-rw-r--r--src/test/ui/resolve/issue-2356.stderr18
4 files changed, 34 insertions, 9 deletions
diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs
index bb9f895c5f3..73a282b1a0e 100644
--- a/src/librustc_resolve/late.rs
+++ b/src/librustc_resolve/late.rs
@@ -345,6 +345,9 @@ struct LateResolutionVisitor<'a, 'b> {
     /// The current self item if inside an ADT (used for better errors).
     current_self_item: Option<NodeId>,
 
+    /// The current enclosing funciton (used for better errors).
+    current_function: Option<Span>,
+
     /// A list of labels as of yet unused. Labels will be removed from this map when
     /// they are used (in a `break` or `continue` statement)
     unused_labels: FxHashMap<NodeId, Span>,
@@ -415,7 +418,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
             }
         }
     }
-    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, _: NodeId) {
+    fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, sp: Span, _: NodeId) {
+        let previous_value = replace(&mut self.current_function, Some(sp));
         debug!("(resolving function) entering function");
         let rib_kind = match fn_kind {
             FnKind::ItemFn(..) => FnItemRibKind,
@@ -441,6 +445,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
                 debug!("(resolving function) leaving function");
             })
         });
+        self.current_function = previous_value;
     }
 
     fn visit_generics(&mut self, generics: &'tcx Generics) {
@@ -546,6 +551,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
             current_trait_assoc_types: Vec::new(),
             current_self_type: None,
             current_self_item: None,
+            current_function: None,
             unused_labels: Default::default(),
             current_type_ascription: Vec::new(),
         }
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index dba4226e983..2721df4c687 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -134,6 +134,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
                     "`self` value is a keyword only available in methods with a `self` parameter",
                 ),
             });
+            if let Some(span) = &self.current_function {
+                err.span_label(*span, "this function doesn't have a `self` parameter");
+            }
             return (err, Vec::new());
         }
 
diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr
index 99b5e01abb1..567d1b3cc75 100644
--- a/src/test/ui/error-codes/E0424.stderr
+++ b/src/test/ui/error-codes/E0424.stderr
@@ -1,14 +1,20 @@
 error[E0424]: expected value, found module `self`
   --> $DIR/E0424.rs:7:9
    |
-LL |         self.bar();
-   |         ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+LL | /     fn foo() {
+LL | |         self.bar();
+   | |         ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+LL | |     }
+   | |_____- this function doesn't have a `self` parameter
 
 error[E0424]: expected unit struct/variant or constant, found module `self`
   --> $DIR/E0424.rs:12:9
    |
-LL |     let self = "self";
-   |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
+LL | / fn main () {
+LL | |     let self = "self";
+   | |         ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
+LL | | }
+   | |_- this function doesn't have a `self` parameter
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/resolve/issue-2356.stderr b/src/test/ui/resolve/issue-2356.stderr
index e0a2088ab8b..329543114a6 100644
--- a/src/test/ui/resolve/issue-2356.stderr
+++ b/src/test/ui/resolve/issue-2356.stderr
@@ -61,8 +61,14 @@ LL |         purr();
 error[E0424]: expected value, found module `self`
   --> $DIR/issue-2356.rs:65:8
    |
-LL |     if self.whiskers > 3 {
-   |        ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+LL | /   fn meow() {
+LL | |     if self.whiskers > 3 {
+   | |        ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+LL | |
+LL | |         println!("MEOW");
+LL | |     }
+LL | |   }
+   | |___- this function doesn't have a `self` parameter
 
 error[E0425]: cannot find function `grow_older` in this scope
   --> $DIR/issue-2356.rs:72:5
@@ -97,8 +103,12 @@ LL |     purr_louder();
 error[E0424]: expected value, found module `self`
   --> $DIR/issue-2356.rs:92:5
    |
-LL |     self += 1;
-   |     ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+LL | / fn main() {
+LL | |     self += 1;
+   | |     ^^^^ `self` value is a keyword only available in methods with a `self` parameter
+LL | |
+LL | | }
+   | |_- this function doesn't have a `self` parameter
 
 error: aborting due to 17 previous errors