Skip to content

Commit 45a5dab

Browse files
authored
Rollup merge of rust-lang#65542 - estebank:kill-static-methods, r=Centril
Refer to "associated functions" instead of "static methods" Fix rust-lang#59782.
2 parents 6d6681a + 2b76c8b commit 45a5dab

File tree

8 files changed

+72
-46
lines changed

8 files changed

+72
-46
lines changed

src/librustc_resolve/error_codes.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -1013,33 +1013,42 @@ fn h1() -> i32 {
10131013
"##,
10141014

10151015
E0424: r##"
1016-
The `self` keyword was used in a static method.
1016+
The `self` keyword was used inside of an associated function without a "`self`
1017+
receiver" parameter.
10171018
10181019
Erroneous code example:
10191020
10201021
```compile_fail,E0424
10211022
struct Foo;
10221023
10231024
impl Foo {
1024-
fn bar(self) {}
1025+
// `bar` is a method, because it has a receiver parameter.
1026+
fn bar(&self) {}
10251027
1028+
// `foo` is not a method, because it has no receiver parameter.
10261029
fn foo() {
1027-
self.bar(); // error: `self` is not available in a static method.
1030+
self.bar(); // error: `self` value is a keyword only available in
1031+
// methods with a `self` parameter
10281032
}
10291033
}
10301034
```
10311035
1032-
Please check if the method's argument list should have contained `self`,
1033-
`&self`, or `&mut self` (in case you didn't want to create a static
1034-
method), and add it if so. Example:
1036+
The `self` keyword can only be used inside methods, which are associated
1037+
functions (functions defined inside of a `trait` or `impl` block) that have a
1038+
`self` receiver as its first parameter, like `self`, `&self`, `&mut self` or
1039+
`self: &mut Pin<Self>` (this last one is an example of an ["abitrary `self`
1040+
type"](https://github.com/rust-lang/rust/issues/44874)).
1041+
1042+
Check if the associated function's parameter list should have contained a `self`
1043+
receiver for it to be a method, and add it if so. Example:
10351044
10361045
```
10371046
struct Foo;
10381047
10391048
impl Foo {
1040-
fn bar(self) {}
1049+
fn bar(&self) {}
10411050
1042-
fn foo(self) {
1051+
fn foo(self) { // `foo` is now a method.
10431052
self.bar(); // ok!
10441053
}
10451054
}

src/librustc_resolve/late.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,9 @@ struct LateResolutionVisitor<'a, 'b> {
345345
/// The current self item if inside an ADT (used for better errors).
346346
current_self_item: Option<NodeId>,
347347

348+
/// The current enclosing funciton (used for better errors).
349+
current_function: Option<Span>,
350+
348351
/// A list of labels as of yet unused. Labels will be removed from this map when
349352
/// they are used (in a `break` or `continue` statement)
350353
unused_labels: FxHashMap<NodeId, Span>,
@@ -415,7 +418,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
415418
}
416419
}
417420
}
418-
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, _: Span, _: NodeId) {
421+
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, declaration: &'tcx FnDecl, sp: Span, _: NodeId) {
422+
let previous_value = replace(&mut self.current_function, Some(sp));
419423
debug!("(resolving function) entering function");
420424
let rib_kind = match fn_kind {
421425
FnKind::ItemFn(..) => FnItemRibKind,
@@ -441,6 +445,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LateResolutionVisitor<'a, '_> {
441445
debug!("(resolving function) leaving function");
442446
})
443447
});
448+
self.current_function = previous_value;
444449
}
445450

446451
fn visit_generics(&mut self, generics: &'tcx Generics) {
@@ -546,6 +551,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
546551
current_trait_assoc_types: Vec::new(),
547552
current_self_type: None,
548553
current_self_item: None,
554+
current_function: None,
549555
unused_labels: Default::default(),
550556
current_type_ascription: Vec::new(),
551557
}

src/librustc_resolve/late/diagnostics.rs

+13-12
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@ impl<'a> LateResolutionVisitor<'a, '_> {
115115
if is_self_type(path, ns) {
116116
syntax::diagnostic_used!(E0411);
117117
err.code(DiagnosticId::Error("E0411".into()));
118-
err.span_label(span, format!("`Self` is only available in impls, traits, \
119-
and type definitions"));
118+
err.span_label(
119+
span,
120+
format!("`Self` is only available in impls, traits, and type definitions"),
121+
);
120122
return (err, Vec::new());
121123
}
122124
if is_self_value(path, ns) {
@@ -125,17 +127,16 @@ impl<'a> LateResolutionVisitor<'a, '_> {
125127
syntax::diagnostic_used!(E0424);
126128
err.code(DiagnosticId::Error("E0424".into()));
127129
err.span_label(span, match source {
128-
PathSource::Pat => {
129-
format!("`self` value is a keyword \
130-
and may not be bound to \
131-
variables or shadowed")
132-
}
133-
_ => {
134-
format!("`self` value is a keyword \
135-
only available in methods \
136-
with `self` parameter")
137-
}
130+
PathSource::Pat => format!(
131+
"`self` value is a keyword and may not be bound to variables or shadowed",
132+
),
133+
_ => format!(
134+
"`self` value is a keyword only available in methods with a `self` parameter",
135+
),
138136
});
137+
if let Some(span) = &self.current_function {
138+
err.span_label(*span, "this function doesn't have a `self` parameter");
139+
}
139140
return (err, Vec::new());
140141
}
141142

src/libsyntax_ext/deriving/clone.rs

+9-13
Original file line numberDiff line numberDiff line change
@@ -174,14 +174,12 @@ fn cs_clone(name: &str,
174174
all_fields = af;
175175
vdata = &variant.data;
176176
}
177-
EnumNonMatchingCollapsed(..) => {
178-
cx.span_bug(trait_span,
179-
&format!("non-matching enum variants in \
180-
`derive({})`",
181-
name))
182-
}
177+
EnumNonMatchingCollapsed(..) => cx.span_bug(trait_span, &format!(
178+
"non-matching enum variants in `derive({})`",
179+
name,
180+
)),
183181
StaticEnum(..) | StaticStruct(..) => {
184-
cx.span_bug(trait_span, &format!("static method in `derive({})`", name))
182+
cx.span_bug(trait_span, &format!("associated function in `derive({})`", name))
185183
}
186184
}
187185

@@ -191,12 +189,10 @@ fn cs_clone(name: &str,
191189
.map(|field| {
192190
let ident = match field.name {
193191
Some(i) => i,
194-
None => {
195-
cx.span_bug(trait_span,
196-
&format!("unnamed field in normal struct in \
197-
`derive({})`",
198-
name))
199-
}
192+
None => cx.span_bug(trait_span, &format!(
193+
"unnamed field in normal struct in `derive({})`",
194+
name,
195+
)),
200196
};
201197
let call = subcall(cx, field);
202198
cx.field_imm(field.span, ident, call)

src/libsyntax_ext/deriving/default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,6 @@ fn default_substructure(cx: &mut ExtCtxt<'_>,
7575
// let compilation continue
7676
DummyResult::raw_expr(trait_span, true)
7777
}
78-
_ => cx.span_bug(trait_span, "Non-static method in `derive(Default)`"),
78+
_ => cx.span_bug(trait_span, "method in `derive(Default)`"),
7979
};
8080
}

src/libsyntax_ext/deriving/generic/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1055,9 +1055,7 @@ impl<'a> MethodDef<'a> {
10551055
})
10561056
.collect()
10571057
} else {
1058-
cx.span_bug(trait_.span,
1059-
"no self arguments to non-static method in generic \
1060-
`derive`")
1058+
cx.span_bug(trait_.span, "no `self` parameter for method in generic `derive`")
10611059
};
10621060

10631061
// body of the inner most destructuring match

src/test/ui/error-codes/E0424.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
error[E0424]: expected value, found module `self`
22
--> $DIR/E0424.rs:7:9
33
|
4-
LL | self.bar();
5-
| ^^^^ `self` value is a keyword only available in methods with `self` parameter
4+
LL | / fn foo() {
5+
LL | | self.bar();
6+
| | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
7+
LL | | }
8+
| |_____- this function doesn't have a `self` parameter
69

710
error[E0424]: expected unit struct/variant or constant, found module `self`
811
--> $DIR/E0424.rs:12:9
912
|
10-
LL | let self = "self";
11-
| ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
13+
LL | / fn main () {
14+
LL | | let self = "self";
15+
| | ^^^^ `self` value is a keyword and may not be bound to variables or shadowed
16+
LL | | }
17+
| |_- this function doesn't have a `self` parameter
1218

1319
error: aborting due to 2 previous errors
1420

src/test/ui/resolve/issue-2356.stderr

+14-4
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,14 @@ LL | purr();
6161
error[E0424]: expected value, found module `self`
6262
--> $DIR/issue-2356.rs:65:8
6363
|
64-
LL | if self.whiskers > 3 {
65-
| ^^^^ `self` value is a keyword only available in methods with `self` parameter
64+
LL | / fn meow() {
65+
LL | | if self.whiskers > 3 {
66+
| | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
67+
LL | |
68+
LL | | println!("MEOW");
69+
LL | | }
70+
LL | | }
71+
| |___- this function doesn't have a `self` parameter
6672

6773
error[E0425]: cannot find function `grow_older` in this scope
6874
--> $DIR/issue-2356.rs:72:5
@@ -97,8 +103,12 @@ LL | purr_louder();
97103
error[E0424]: expected value, found module `self`
98104
--> $DIR/issue-2356.rs:92:5
99105
|
100-
LL | self += 1;
101-
| ^^^^ `self` value is a keyword only available in methods with `self` parameter
106+
LL | / fn main() {
107+
LL | | self += 1;
108+
| | ^^^^ `self` value is a keyword only available in methods with a `self` parameter
109+
LL | |
110+
LL | | }
111+
| |_- this function doesn't have a `self` parameter
102112

103113
error: aborting due to 17 previous errors
104114

0 commit comments

Comments
 (0)