about summary refs log tree commit diff
path: root/compiler/rustc_error_codes/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-03-30 12:28:50 +0000
committerbors <bors@rust-lang.org>2022-03-30 12:28:50 +0000
commit3e7514670db841a7f0d7656f3b13b1c8b2c11599 (patch)
treeea65f9f3d772de91ee27bf207de8cbf7ff997e8f /compiler/rustc_error_codes/src
parente50ff9b4521234e56ff46f8ed0372d5cb5689654 (diff)
parent46340f20497fd9f30e08d5c30413f6f45164da89 (diff)
downloadrust-3e7514670db841a7f0d7656f3b13b1c8b2c11599.tar.gz
rust-3e7514670db841a7f0d7656f3b13b1c8b2c11599.zip
Auto merge of #94963 - lcnr:inherent-impls-std, r=oli-obk,m-ou-se
allow arbitrary inherent impls for builtin types in core

Part of https://github.com/rust-lang/compiler-team/issues/487. Slightly adjusted after some talks with `@m-ou-se` about the requirements of `t-libs-api`.

This adds a crate attribute `#![rustc_coherence_is_core]` which allows arbitrary impls for builtin types in core.

For other library crates impls for builtin types should be avoided if possible. We do have to allow the existing stable impls however. To prevent us from accidentally adding more of these in the future, there is a second attribute `#[rustc_allow_incoherent_impl]` which has to be added to **all impl items**. This only supports impls for builtin types but can easily be extended to additional types in a future PR.

This implementation does not check for overlaps in these impls. Perfectly checking that requires us to check the coherence of these incoherent impls in every crate, as two distinct dependencies may add overlapping methods. It should be easy enough to detect if it goes wrong and the attribute is only intended for use inside of std.

The first two commits are mostly unrelated cleanups.
Diffstat (limited to 'compiler/rustc_error_codes/src')
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0118.md29
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0390.md24
2 files changed, 26 insertions, 27 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0118.md b/compiler/rustc_error_codes/src/error_codes/E0118.md
index 345ec341c3f..8033aa8384c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0118.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0118.md
@@ -4,7 +4,7 @@ enum, union, or trait object.
 Erroneous code example:
 
 ```compile_fail,E0118
-impl (u8, u8) { // error: no nominal type found for inherent implementation
+impl fn(u8) { // error: no nominal type found for inherent implementation
     fn get_state(&self) -> String {
         // ...
     }
@@ -20,8 +20,8 @@ trait LiveLongAndProsper {
     fn get_state(&self) -> String;
 }
 
-// and now you can implement it on (u8, u8)
-impl LiveLongAndProsper for (u8, u8) {
+// and now you can implement it on fn(u8)
+impl LiveLongAndProsper for fn(u8) {
     fn get_state(&self) -> String {
         "He's dead, Jim!".to_owned()
     }
@@ -33,7 +33,7 @@ For example, `NewType` is a newtype over `Foo` in `struct NewType(Foo)`.
 Example:
 
 ```
-struct TypeWrapper((u8, u8));
+struct TypeWrapper(fn(u8));
 
 impl TypeWrapper {
     fn get_state(&self) -> String {
@@ -41,24 +41,3 @@ 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) {}
-}
-```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0390.md b/compiler/rustc_error_codes/src/error_codes/E0390.md
index 7a13160d098..26a9dd331ce 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0390.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0390.md
@@ -8,8 +8,7 @@ struct Foo {
 }
 
 impl *mut Foo {}
-// error: only a single inherent implementation marked with
-//        `#[lang = "mut_ptr"]` is allowed for the `*mut T` primitive
+// error: cannot define inherent `impl` for primitive types
 ```
 
 This isn't allowed, but using a trait to implement a method or constant
@@ -29,3 +28,24 @@ impl Bar for *mut Foo {
     fn bar() {} // ok!
 }
 ```
+
+Instead of defining an inherent implementation on a reference, you could also
+move the reference inside the implementation:
+
+```compile_fail,E0390
+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) {}
+}
+```