Auto merge of #76028 - aticu:improve_e0118, r=estebank,jyn514,GuillaumeGomez
Improve E0118 - Changes the "base type" terminology to "nominal type" (according to the [reference](https://doc.rust-lang.org/stable/reference/items/implementations.html#inherent-implementations)). - Suggests removing a reference, if one is present on the type. - Clarify what is meant by a "nominal type". closes #69392 This is my first not-entirely-trivial PR, so please let me know if I missed anything or if something could be improved. Though I probably won't be able to fix anything in the upcoming week.
This commit is contained in:
commit
95386b656e
|
@ -1,10 +1,10 @@
|
||||||
An inherent implementation was defined for something which isn't a struct nor
|
An inherent implementation was defined for something which isn't a struct,
|
||||||
an enum.
|
enum, union, or trait object.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0118
|
```compile_fail,E0118
|
||||||
impl (u8, u8) { // error: no base type found for inherent implementation
|
impl (u8, u8) { // error: no nominal type found for inherent implementation
|
||||||
fn get_state(&self) -> String {
|
fn get_state(&self) -> String {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
@ -41,3 +41,24 @@ impl TypeWrapper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Instead of defining an inherent implementation on a reference, you could also
|
||||||
|
move the reference inside the implementation:
|
||||||
|
|
||||||
|
```compile_fail,E0118
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl &Foo { // error: no nominal type found for inherent implementation
|
||||||
|
fn bar(self, other: Self) {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
becomes
|
||||||
|
|
||||||
|
```
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl Foo {
|
||||||
|
fn bar(&self, other: &Self) {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -308,18 +308,25 @@ impl ItemLikeVisitor<'v> for InherentCollect<'tcx> {
|
||||||
}
|
}
|
||||||
ty::Error(_) => {}
|
ty::Error(_) => {}
|
||||||
_ => {
|
_ => {
|
||||||
struct_span_err!(
|
let mut err = struct_span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
ty.span,
|
ty.span,
|
||||||
E0118,
|
E0118,
|
||||||
"no base type found for inherent implementation"
|
"no nominal type found for inherent implementation"
|
||||||
)
|
);
|
||||||
.span_label(ty.span, "impl requires a base type")
|
|
||||||
.note(
|
err.span_label(ty.span, "impl requires a nominal type")
|
||||||
"either implement a trait on it or create a newtype \
|
.note("either implement a trait on it or create a newtype to wrap it instead");
|
||||||
to wrap it instead",
|
|
||||||
)
|
if let ty::Ref(_, subty, _) = self_ty.kind() {
|
||||||
.emit();
|
err.note(&format!(
|
||||||
|
"you could also try moving the reference to \
|
||||||
|
uses of `{}` (such as `self`) within the implementation",
|
||||||
|
subty
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
err.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
struct Foo;
|
||||||
|
|
||||||
|
impl &mut Foo {
|
||||||
|
//~^ ERROR E0118
|
||||||
|
fn bar(self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0118]: no nominal type found for inherent implementation
|
||||||
|
--> $DIR/E0118-2.rs:3:6
|
||||||
|
|
|
||||||
|
LL | impl &mut Foo {
|
||||||
|
| ^^^^^^^^ impl requires a nominal type
|
||||||
|
|
|
||||||
|
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||||
|
= note: you could also try moving the reference to uses of `Foo` (such as `self`) within the implementation
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0118`.
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0118]: no base type found for inherent implementation
|
error[E0118]: no nominal type found for inherent implementation
|
||||||
--> $DIR/E0118.rs:1:6
|
--> $DIR/E0118.rs:1:6
|
||||||
|
|
|
|
||||||
LL | impl (u8, u8) {
|
LL | impl (u8, u8) {
|
||||||
| ^^^^^^^^ impl requires a base type
|
| ^^^^^^^^ impl requires a nominal type
|
||||||
|
|
|
|
||||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,8 @@ mod aliases_pub {
|
||||||
type AssocAlias = m::Pub3;
|
type AssocAlias = m::Pub3;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <Priv as PrivTr>::AssocAlias { //~ ERROR no base type found for inherent implementation
|
impl <Priv as PrivTr>::AssocAlias {
|
||||||
|
//~^ ERROR no nominal type found for inherent implementation
|
||||||
pub fn f(arg: Priv) {} // private type `aliases_pub::Priv` in public interface
|
pub fn f(arg: Priv) {} // private type `aliases_pub::Priv` in public interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +28,8 @@ mod aliases_priv {
|
||||||
type AssocAlias = Priv3;
|
type AssocAlias = Priv3;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <Priv as PrivTr>::AssocAlias { //~ ERROR no base type found for inherent implementation
|
impl <Priv as PrivTr>::AssocAlias {
|
||||||
|
//~^ ERROR no nominal type found for inherent implementation
|
||||||
pub fn f(arg: Priv) {} // OK
|
pub fn f(arg: Priv) {} // OK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
error[E0118]: no base type found for inherent implementation
|
error[E0118]: no nominal type found for inherent implementation
|
||||||
--> $DIR/private-in-public-ill-formed.rs:14:10
|
--> $DIR/private-in-public-ill-formed.rs:14:10
|
||||||
|
|
|
|
||||||
LL | impl <Priv as PrivTr>::AssocAlias {
|
LL | impl <Priv as PrivTr>::AssocAlias {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a base type
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||||
|
|
|
|
||||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||||
|
|
||||||
error[E0118]: no base type found for inherent implementation
|
error[E0118]: no nominal type found for inherent implementation
|
||||||
--> $DIR/private-in-public-ill-formed.rs:30:10
|
--> $DIR/private-in-public-ill-formed.rs:31:10
|
||||||
|
|
|
|
||||||
LL | impl <Priv as PrivTr>::AssocAlias {
|
LL | impl <Priv as PrivTr>::AssocAlias {
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a base type
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
||||||
|
|
|
|
||||||
= note: either implement a trait on it or create a newtype to wrap it instead
|
= note: either implement a trait on it or create a newtype to wrap it instead
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue