Rollup merge of #65542 - estebank:kill-static-methods, r=Centril
Refer to "associated functions" instead of "static methods" Fix #59782.
This commit is contained in:
commit
fab74044dd
8 changed files with 72 additions and 46 deletions
|
|
@ -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!
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)`"),
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue