about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-10-19 07:10:07 +0200
committerGitHub <noreply@github.com>2019-10-19 07:10:07 +0200
commitfab74044dde091682869039c2bbbb764d4f70123 (patch)
tree3b0d004f2874d5b79e45e8e6db1bd07b8b0f577d
parent27f8c7990e26900e72184f0fbe55da110782be72 (diff)
parent2b76c8b95ff866d8806fdc82fe270c4df02efc0b (diff)
downloadrust-fab74044dde091682869039c2bbbb764d4f70123.tar.gz
rust-fab74044dde091682869039c2bbbb764d4f70123.zip
Rollup merge of #65542 - estebank:kill-static-methods, r=Centril
Refer to "associated functions" instead of "static methods"

Fix #59782.
-rw-r--r--src/librustc_resolve/error_codes.rs25
-rw-r--r--src/librustc_resolve/late.rs8
-rw-r--r--src/librustc_resolve/late/diagnostics.rs25
-rw-r--r--src/libsyntax_ext/deriving/clone.rs22
-rw-r--r--src/libsyntax_ext/deriving/default.rs2
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs4
-rw-r--r--src/test/ui/error-codes/E0424.stderr14
-rw-r--r--src/test/ui/resolve/issue-2356.stderr18
8 files changed, 72 insertions, 46 deletions
diff --git a/src/librustc_resolve/error_codes.rs b/src/librustc_resolve/error_codes.rs
index 8ccb27078d5..cd6189c681d 100644
--- a/src/librustc_resolve/error_codes.rs
+++ b/src/librustc_resolve/error_codes.rs
@@ -1013,7 +1013,8 @@ fn h1() -> i32 {
 "##,
 
 E0424: r##"
-The `self` keyword was used in a static method.
+The `self` keyword was used inside of an associated function without a "`self`
+receiver" parameter.
 
 Erroneous code example:
 
@@ -1021,25 +1022,33 @@ Erroneous code example:
 struct Foo;
 
 impl Foo {
-    fn bar(self) {}
+    // `bar` is a method, because it has a receiver parameter.
+    fn bar(&self) {}
 
+    // `foo` is not a method, because it has no receiver parameter.
     fn foo() {
-        self.bar(); // error: `self` is not available in a static method.
+        self.bar(); // error: `self` value is a keyword only available in
+                    //        methods with a `self` parameter
     }
 }
 ```
 
-Please check if the method's argument list should have contained `self`,
-`&self`, or `&mut self` (in case you didn't want to create a static
-method), and add it if so. Example:
+The `self` keyword can only be used inside methods, which are associated
+functions (functions defined inside of a `trait` or `impl` block) that have a
+`self` receiver as its first parameter, like `self`, `&self`, `&mut self` or
+`self: &mut Pin<Self>` (this last one is an example of an ["abitrary `self`
+type"](https://github.com/rust-lang/rust/issues/44874)).
+
+Check if the associated function's parameter list should have contained a `self`
+receiver for it to be a method, and add it if so. Example:
 
 ```
 struct Foo;
 
 impl Foo {
-    fn bar(self) {}
+    fn bar(&self) {}
 
-    fn foo(self) {
+    fn foo(self) { // `foo` is now a method.
         self.bar(); // ok!
     }
 }
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 412734eabe0..2721df4c687 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -115,8 +115,10 @@ impl<'a> LateResolutionVisitor<'a, '_> {
         if is_self_type(path, ns) {
             syntax::diagnostic_used!(E0411);
             err.code(DiagnosticId::Error("E0411".into()));
-            err.span_label(span, format!("`Self` is only available in impls, traits, \
-                                          and type definitions"));
+            err.span_label(
+                span,
+                format!("`Self` is only available in impls, traits, and type definitions"),
+            );
             return (err, Vec::new());
         }
         if is_self_value(path, ns) {
@@ -125,17 +127,16 @@ impl<'a> LateResolutionVisitor<'a, '_> {
             syntax::diagnostic_used!(E0424);
             err.code(DiagnosticId::Error("E0424".into()));
             err.span_label(span, match source {
-                PathSource::Pat => {
-                    format!("`self` value is a keyword \
-                             and may not be bound to \
-                             variables or shadowed")
-                }
-                _ => {
-                    format!("`self` value is a keyword \
-                             only available in methods \
-                             with `self` parameter")
-                }
+                PathSource::Pat => format!(
+                    "`self` value is a keyword and may not be bound to variables or shadowed",
+                ),
+                _ => format!(
+                    "`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/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs
index eb7d480aa98..67ef69babdc 100644
--- a/src/libsyntax_ext/deriving/clone.rs
+++ b/src/libsyntax_ext/deriving/clone.rs
@@ -174,14 +174,12 @@ fn cs_clone(name: &str,
             all_fields = af;
             vdata = &variant.data;
         }
-        EnumNonMatchingCollapsed(..) => {
-            cx.span_bug(trait_span,
-                        &format!("non-matching enum variants in \
-                                 `derive({})`",
-                                 name))
-        }
+        EnumNonMatchingCollapsed(..) => cx.span_bug(trait_span, &format!(
+            "non-matching enum variants in `derive({})`",
+            name,
+        )),
         StaticEnum(..) | StaticStruct(..) => {
-            cx.span_bug(trait_span, &format!("static method in `derive({})`", name))
+            cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
         }
     }
 
@@ -191,12 +189,10 @@ fn cs_clone(name: &str,
                 .map(|field| {
                     let ident = match field.name {
                         Some(i) => i,
-                        None => {
-                            cx.span_bug(trait_span,
-                                        &format!("unnamed field in normal struct in \
-                                                `derive({})`",
-                                                    name))
-                        }
+                        None => cx.span_bug(trait_span, &format!(
+                            "unnamed field in normal struct in `derive({})`",
+                            name,
+                        )),
                     };
                     let call = subcall(cx, field);
                     cx.field_imm(field.span, ident, call)
diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs
index 6176791c31b..cfc0f3cd6cb 100644
--- a/src/libsyntax_ext/deriving/default.rs
+++ b/src/libsyntax_ext/deriving/default.rs
@@ -75,6 +75,6 @@ fn default_substructure(cx: &mut ExtCtxt<'_>,
             // let compilation continue
             DummyResult::raw_expr(trait_span, true)
         }
-        _ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`"),
+        _ => cx.span_bug(trait_span, "method in `derive(Default)`"),
     };
 }
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 1886a5154b7..216338c1a88 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1055,9 +1055,7 @@ impl<'a> MethodDef<'a> {
                 })
                 .collect()
         } else {
-            cx.span_bug(trait_.span,
-                        "no self arguments to non-static method in generic \
-                         `derive`")
+            cx.span_bug(trait_.span, "no `self` parameter for method in generic `derive`")
         };
 
         // body of the inner most destructuring match
diff --git a/src/test/ui/error-codes/E0424.stderr b/src/test/ui/error-codes/E0424.stderr
index d67a2660dac..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 `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 7790383843e..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 `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 `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