Refer to "self type" instead of "receiver type"

This commit is contained in:
Esteban Küber 2019-09-02 18:21:58 -07:00
parent dfd43f0fdd
commit 3ea932ab0e
25 changed files with 155 additions and 75 deletions

View File

@ -1627,7 +1627,7 @@ impl<'tcx> ObligationCause<'tcx> {
MainFunctionType => Error0580("main function has wrong type"),
StartFunctionType => Error0308("start function has wrong type"),
IntrinsicType => Error0308("intrinsic has wrong type"),
MethodReceiver => Error0308("mismatched method receiver"),
MethodReceiver => Error0308("mismatched `self` parameter type"),
// In the case where we have no more specific thing to
// say, also take a look at the error code, maybe we can

View File

@ -47,13 +47,15 @@ impl ObjectSafetyViolation {
"the trait cannot use `Self` as a type parameter \
in the supertraits or where-clauses".into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
format!("method `{}` has no receiver", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
format!("method `{}` references the `Self` type \
in its arguments or return type", name).into(),
ObjectSafetyViolation::Method(name,
MethodViolationCode::WhereClauseReferencesSelf(_)) =>
format!("method `{}` references the `Self` type in where clauses", name).into(),
format!("associated function `{}` has no `self` parameter", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) => format!(
"method `{}` references the `Self` type in its arguments or return type",
name,
).into(),
ObjectSafetyViolation::Method(
name,
MethodViolationCode::WhereClauseReferencesSelf(_),
) => format!("method `{}` references the `Self` type in where clauses", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
format!("method `{}` has generic type parameters", name).into(),
ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>

View File

@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>(
substituted_predicates
}
const HELP_FOR_SELF_TYPE: &str =
"consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
of the previous types except `Self`)";
fn check_method_receiver<'fcx, 'tcx>(
fcx: &FnCtxt<'fcx, 'tcx>,
method_sig: &hir::MethodSig,
method: &ty::AssocItem,
self_ty: Ty<'tcx>,
) {
const HELP_FOR_SELF_TYPE: &str =
"consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
`self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
of the previous types except `Self`)";
// Check that the method has a valid receiver type, given the type `Self`.
debug!("check_method_receiver({:?}, self_ty={:?})",
method, self_ty);
debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
if !method.method_has_self_argument {
return;
@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>(
if fcx.tcx.features().arbitrary_self_types {
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
// Report error; `arbitrary_self_types` was enabled.
fcx.tcx.sess.diagnostic().mut_span_err(
span, &format!("invalid method receiver type: {:?}", receiver_ty)
).note("type of `self` must be `Self` or a type that dereferences to it")
.help(HELP_FOR_SELF_TYPE)
.code(DiagnosticId::Error("E0307".into()))
.emit();
e0307(fcx, span, receiver_ty);
}
} else {
if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
@ -830,16 +825,21 @@ fn check_method_receiver<'fcx, 'tcx>(
.emit();
} else {
// Report error; would not have worked with `arbitrary_self_types`.
e0307(fcx, span, receiver_ty);
}
}
}
}
fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
fcx.tcx.sess.diagnostic().mut_span_err(
span, &format!("invalid method receiver type: {:?}", receiver_ty)
).note("type must be `Self` or a type that dereferences to it")
span,
&format!("invalid `self` parameter type: {:?}", receiver_ty)
).note("type of `self` must be `Self` or a type that dereferences to it")
.help(HELP_FOR_SELF_TYPE)
.code(DiagnosticId::Error("E0307".into()))
.emit();
}
}
}
}
/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
/// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly

View File

@ -2425,6 +2425,83 @@ struct Bar<S, T> { x: Foo<S, T> }
```
"##,
E0307: r##"
This error indicates that the `self` parameter in a method has an invalid
"reciever type".
Methods take a special first parameter, of which there are three variants:
`self`, `&self`, and `&mut self`. The type `Self` acts as an alias to the
type of the current trait implementor, or "receiver type". Besides the
already mentioned `Self`, `&Self` and `&mut Self` valid receiver types, the
following are also valid, if less common: `self: Box<Self>`,
`self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>` (where P is one of
the previous types except `Self`).
```
# struct Foo;
trait Trait {
fn foo(&self);
// ^^^^^ this let's you refer to the type that implements this trait
}
impl Trait for Foo {
// ^^^ this is the "receiver type"
fn foo(&self) {}
// ^^^^^ this is of type `Foo`
}
```
The above is equivalent to:
```
# struct Foo;
# trait Trait {
# fn foo(&self);
# }
impl Trait for Foo {
fn foo(&self: &Foo) {}
}
```
When using an invalid reciver type, like in the following example,
```compile_fail,E0307
# struct Foo;
# struct Bar;
# trait Trait {
# fn foo(&self);
# }
impl Trait for Struct {
fn foo(&self: &Bar) {}
}
```
The nightly feature [Arbintrary self types][AST] extends the accepted
receiver type to also include any type that can dereference to `Self`:
```
#![feature(arbitrary_self_types)]
struct Foo;
struct Bar;
// Because you can dereference `Bar` into `Foo`...
impl std::ops::Deref for Bar {
type Target = Foo;
fn deref(&self) -> &Foo {
&Foo
}
}
impl Foo {
fn foo(self: Bar) {}
// ^^^^^^^^^ ...it can be used as the receiver type
}
```
[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html
"##,
E0321: r##"
A cross-crate opt-out trait was implemented on something which wasn't a struct
or enum type. Erroneous code example:
@ -4851,7 +4928,6 @@ register_diagnostics! {
// E0247,
// E0248, // value used as a type, now reported earlier during resolution as E0412
// E0249,
E0307, // invalid method `self` type
// E0319, // trait impls for defaulted traits allowed just for structs/enums
// E0372, // coherence not object safe
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion

View File

@ -62,7 +62,7 @@ error[E0038]: the trait `X` cannot be made into an object
LL | impl dyn X {
| ^^^^^ the trait `X` cannot be made into an object
|
= note: method `xxx` has no receiver
= note: associated function `xxx` has no `self` parameter
error: aborting due to 9 previous errors

View File

@ -8,7 +8,7 @@ fn main() {
let trait_obj: &dyn SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038
//~| method `foo` has no receiver
//~| associated function `foo` has no `self` parameter
let &invalid = trait_obj;
//~^ ERROR E0033

View File

@ -10,7 +10,7 @@ error[E0038]: the trait `SomeTrait` cannot be made into an object
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
= note: method `foo` has no receiver
= note: associated function `foo` has no `self` parameter
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
--> $DIR/E0033-teach.rs:13:9

View File

@ -6,7 +6,7 @@ fn main() {
let trait_obj: &dyn SomeTrait = SomeTrait;
//~^ ERROR expected value, found trait `SomeTrait`
//~| ERROR E0038
//~| method `foo` has no receiver
//~| associated function `foo` has no `self` parameter
let &invalid = trait_obj;
//~^ ERROR E0033

View File

@ -10,7 +10,7 @@ error[E0038]: the trait `SomeTrait` cannot be made into an object
LL | let trait_obj: &dyn SomeTrait = SomeTrait;
| ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
|
= note: method `foo` has no receiver
= note: associated function `foo` has no `self` parameter
error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
--> $DIR/E0033.rs:11:9

View File

@ -6,11 +6,11 @@ struct Foo<'a,'b> {
impl<'a,'b> Foo<'a,'b> {
fn bar(self:
Foo<'b,'a>
//~^ ERROR mismatched method receiver
//~^ ERROR mismatched `self` parameter type
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch
//~| ERROR mismatched method receiver
//~| ERROR mismatched `self` parameter type
//~| expected type `Foo<'a, 'b>`
//~| found type `Foo<'b, 'a>`
//~| lifetime mismatch

View File

@ -1,4 +1,4 @@
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/explicit-self-lifetime-mismatch.rs:8:12
|
LL | Foo<'b,'a>
@ -17,7 +17,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl<'a,'b> Foo<'a,'b> {
| ^^
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/explicit-self-lifetime-mismatch.rs:8:12
|
LL | Foo<'b,'a>

View File

@ -4,11 +4,11 @@ struct Foo<'a> {
impl <'a> Foo<'a>{
fn bar(self: &mut Foo) {
//~^ mismatched method receiver
//~^ mismatched `self` parameter type
//~| expected type `Foo<'a>`
//~| found type `Foo<'_>`
//~| lifetime mismatch
//~| mismatched method receiver
//~| mismatched `self` parameter type
//~| expected type `Foo<'a>`
//~| found type `Foo<'_>`
//~| lifetime mismatch

View File

@ -1,4 +1,4 @@
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17740.rs:6:18
|
LL | fn bar(self: &mut Foo) {
@ -23,7 +23,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl <'a> Foo<'a>{
| ^^
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17740.rs:6:18
|
LL | fn bar(self: &mut Foo) {

View File

@ -6,8 +6,8 @@ impl Pair<
isize
> {
fn say(self: &Pair<&str, isize>) {
//~^ ERROR mismatched method receiver
//~| ERROR mismatched method receiver
//~^ ERROR mismatched `self` parameter type
//~| ERROR mismatched `self` parameter type
println!("{:?}", self);
}
}

View File

@ -1,4 +1,4 @@
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17905-2.rs:8:18
|
LL | fn say(self: &Pair<&str, isize>) {
@ -21,7 +21,7 @@ note: ...does not necessarily outlive the lifetime '_ as defined on the impl at
LL | &str,
| ^
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/issue-17905-2.rs:8:18
|
LL | fn say(self: &Pair<&str, isize>) {

View File

@ -4,7 +4,7 @@ error[E0038]: the trait `Qiz` cannot be made into an object
LL | foos: &'static [&'static (dyn Qiz + 'static)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
|
= note: method `qiz` has no receiver
= note: associated function `qiz` has no `self` parameter
error: aborting due to previous error

View File

@ -1,7 +1,6 @@
pub trait Trait {
fn dyn_instead_of_self(self: Box<dyn Trait>);
//~^ ERROR invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
//~^ ERROR invalid `self` parameter type
}
pub fn main() {
}
pub fn main() {}

View File

@ -1,11 +1,12 @@
error[E0307]: invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
error[E0307]: invalid `self` parameter type: std::boxed::Box<(dyn Trait + 'static)>
--> $DIR/issue-56806.rs:2:34
|
LL | fn dyn_instead_of_self(self: Box<dyn Trait>);
| ^^^^^^^^^^^^^^
|
= note: type must be `Self` or a type that dereferences to it
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0307`.

View File

@ -4,7 +4,7 @@ error[E0038]: the trait `Foo` cannot be made into an object
LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
|
= note: method `foo` has no receiver
= note: associated function `foo` has no `self` parameter
error: aborting due to previous error

View File

@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
LL | fn bar(_x: Foo) {}
| ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
|
= note: method `bar` has no receiver
= note: associated function `bar` has no `self` parameter
error: aborting due to previous error

View File

@ -3,7 +3,7 @@
struct SomeType {}
trait Foo {
fn handler(self: &SomeType); //~ ERROR invalid method receiver type
fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type
}
fn main() {}

View File

@ -1,11 +1,12 @@
error[E0307]: invalid method receiver type: &SomeType
error[E0307]: invalid `self` parameter type: &SomeType
--> $DIR/issue-27522.rs:6:22
|
LL | fn handler(self: &SomeType);
| ^^^^^^^^^
|
= note: type must be `Self` or a type that dereferences to it
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error: aborting due to previous error
For more information about this error, try `rustc --explain E0307`.

View File

@ -4,7 +4,7 @@ error[E0038]: the trait `Tr` cannot be made into an object
LL | let _: &dyn Tr = &St;
| ^^^ the trait `Tr` cannot be made into an object
|
= note: method `foo` has no receiver
= note: associated function `foo` has no `self` parameter
= note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
error[E0038]: the trait `Tr` cannot be made into an object
@ -13,7 +13,7 @@ error[E0038]: the trait `Tr` cannot be made into an object
LL | let _: &dyn Tr = &St;
| ^^^^^^^ the trait `Tr` cannot be made into an object
|
= note: method `foo` has no receiver
= note: associated function `foo` has no `self` parameter
error: aborting due to 2 previous errors

View File

@ -6,7 +6,7 @@ struct Foo {
impl Foo {
fn foo(self: isize, x: isize) -> isize {
//~^ ERROR invalid method receiver type
//~^ ERROR invalid `self` parameter type
self.f + x
}
}
@ -17,11 +17,11 @@ struct Bar<T> {
impl<T> Bar<T> {
fn foo(self: Bar<isize>, x: isize) -> isize {
//~^ ERROR invalid method receiver type
//~^ ERROR invalid `self` parameter type
x
}
fn bar(self: &Bar<usize>, x: isize) -> isize {
//~^ ERROR invalid method receiver type
//~^ ERROR invalid `self` parameter type
x
}
}
@ -34,14 +34,14 @@ trait SomeTrait {
impl<'a, T> SomeTrait for &'a Bar<T> {
fn dummy1(self: &&'a Bar<T>) { }
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver
//~^ ERROR mismatched method receiver
fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched `self` parameter type
//~^ ERROR mismatched `self` parameter type
fn dummy3(self: &&Bar<T>) {}
//~^ ERROR mismatched method receiver
//~^ ERROR mismatched `self` parameter type
//~| expected type `&'a Bar<T>`
//~| found type `&Bar<T>`
//~| lifetime mismatch
//~| ERROR mismatched method receiver
//~| ERROR mismatched `self` parameter type
//~| expected type `&'a Bar<T>`
//~| found type `&Bar<T>`
//~| lifetime mismatch

View File

@ -1,31 +1,31 @@
error[E0307]: invalid method receiver type: isize
error[E0307]: invalid `self` parameter type: isize
--> $DIR/ufcs-explicit-self-bad.rs:8:18
|
LL | fn foo(self: isize, x: isize) -> isize {
| ^^^^^
|
= note: type must be `Self` or a type that dereferences to it
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0307]: invalid method receiver type: Bar<isize>
error[E0307]: invalid `self` parameter type: Bar<isize>
--> $DIR/ufcs-explicit-self-bad.rs:19:18
|
LL | fn foo(self: Bar<isize>, x: isize) -> isize {
| ^^^^^^^^^^
|
= note: type must be `Self` or a type that dereferences to it
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0307]: invalid method receiver type: &Bar<usize>
error[E0307]: invalid `self` parameter type: &Bar<usize>
--> $DIR/ufcs-explicit-self-bad.rs:23:18
|
LL | fn bar(self: &Bar<usize>, x: isize) -> isize {
| ^^^^^^^^^^^
|
= note: type must be `Self` or a type that dereferences to it
= note: type of `self` must be `Self` or a type that dereferences to it
= help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:37:21
|
LL | fn dummy2(self: &Bar<T>) {}
@ -44,7 +44,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl<'a, T> SomeTrait for &'a Bar<T> {
| ^^
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:37:21
|
LL | fn dummy2(self: &Bar<T>) {}
@ -63,7 +63,7 @@ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the m
LL | fn dummy2(self: &Bar<T>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:39:21
|
LL | fn dummy3(self: &&Bar<T>) {}
@ -82,7 +82,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
LL | impl<'a, T> SomeTrait for &'a Bar<T> {
| ^^
error[E0308]: mismatched method receiver
error[E0308]: mismatched `self` parameter type
--> $DIR/ufcs-explicit-self-bad.rs:39:21
|
LL | fn dummy3(self: &&Bar<T>) {}
@ -103,4 +103,5 @@ LL | fn dummy3(self: &&Bar<T>) {}
error: aborting due to 7 previous errors
For more information about this error, try `rustc --explain E0308`.
Some errors have detailed explanations: E0307, E0308.
For more information about an error, try `rustc --explain E0307`.