about summary refs log tree commit diff
path: root/compiler/rustc_error_codes/src
diff options
context:
space:
mode:
authorBoxy <rust@boxyuwu.dev>2025-02-25 21:27:44 +0000
committerBoxy <rust@boxyuwu.dev>2025-02-25 21:27:44 +0000
commitd9683df7c2f6d4141b1321e27635d2ce3167eaa4 (patch)
treedce0d46d1b7d624ec9b9b09b2c1854f6245a5ff4 /compiler/rustc_error_codes/src
parent46392d1661540e256fd9573d8f06c2784a58c983 (diff)
parent4ecd70ddd1039a3954056c1071e40278048476fa (diff)
downloadrust-d9683df7c2f6d4141b1321e27635d2ce3167eaa4.tar.gz
rust-d9683df7c2f6d4141b1321e27635d2ce3167eaa4.zip
Merge from rustc
Diffstat (limited to 'compiler/rustc_error_codes/src')
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md14
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0374.md53
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0375.md47
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0376.md38
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0377.md23
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0802.md94
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0803.md46
-rw-r--r--compiler/rustc_error_codes/src/lib.rs2
8 files changed, 189 insertions, 128 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index efbfa0851a8..909da368f2b 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
@@ -7,12 +7,8 @@ Erroneous code example:
 #![allow(internal_features)]
 
 #[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-fn size_of<T, U>() -> usize // error: intrinsic has wrong number
-                            //        of type parameters
-{
-    loop {}
-}
+fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
+                             //        of type parameters
 ```
 
 Please check that you provided the right number of type parameters
@@ -24,9 +20,5 @@ Example:
 #![allow(internal_features)]
 
 #[rustc_intrinsic]
-#[rustc_intrinsic_must_be_overridden]
-fn size_of<T>() -> usize // ok!
-{
-    loop {}
-}
+fn size_of<T>() -> usize; // ok!
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0374.md b/compiler/rustc_error_codes/src/error_codes/E0374.md
index 6d7dc88823c..63c243b54ff 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0374.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0374.md
@@ -1,5 +1,5 @@
-`CoerceUnsized` was implemented on a struct which does not contain a field with
-an unsized type.
+`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which does not
+contain a field that is being unsized.
 
 Example of erroneous code:
 
@@ -11,47 +11,20 @@ struct Foo<T: ?Sized> {
     a: i32,
 }
 
-// error: Struct `Foo` has no unsized fields that need `CoerceUnsized`.
+// error: Struct `Foo` has no unsized fields that need to be coerced.
 impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
     where T: CoerceUnsized<U> {}
 ```
 
-An [unsized type][1] is any type where the compiler does not know the length or
-alignment of at compile time. Any struct containing an unsized type is also
-unsized.
+`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
+like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
+is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
+trait.
 
-[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
+If the struct doesn't have any fields of unsized types then there is no
+meaningful way to implement `CoerceUnsized` or `DispatchFromDyn`, since
+there is no coercion taking place.
 
-`CoerceUnsized` is used to coerce one struct containing an unsized type
-into another struct containing a different unsized type. If the struct
-doesn't have any fields of unsized types then you don't need explicit
-coercion to get the types you want. To fix this you can either
-not try to implement `CoerceUnsized` or you can add a field that is
-unsized to the struct.
-
-Example:
-
-```
-#![feature(coerce_unsized)]
-use std::ops::CoerceUnsized;
-
-// We don't need to impl `CoerceUnsized` here.
-struct Foo {
-    a: i32,
-}
-
-// We add the unsized type field to the struct.
-struct Bar<T: ?Sized> {
-    a: i32,
-    b: T,
-}
-
-// The struct has an unsized field so we can implement
-// `CoerceUnsized` for it.
-impl<T, U> CoerceUnsized<Bar<U>> for Bar<T>
-    where T: CoerceUnsized<U> {}
-```
-
-Note that `CoerceUnsized` is mainly used by smart pointers like `Box`, `Rc`
-and `Arc` to be able to mark that they can coerce unsized types that they
-are pointing at.
+Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
+like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
+that they are pointing at.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0375.md b/compiler/rustc_error_codes/src/error_codes/E0375.md
index 71e53057165..7abb3b6afd0 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0375.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0375.md
@@ -1,5 +1,5 @@
-`CoerceUnsized` was implemented on a struct which contains more than one field
-with an unsized type.
+`CoerceUnsized` or `DispatchFromDyn` was implemented on a struct which contains
+more than one field that is being unsized.
 
 Erroneous code example:
 
@@ -17,39 +17,14 @@ struct Foo<T: ?Sized, U: ?Sized> {
 impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
 ```
 
-A struct with more than one field containing an unsized type cannot implement
-`CoerceUnsized`. This only occurs when you are trying to coerce one of the
-types in your struct to another type in the struct. In this case we try to
-impl `CoerceUnsized` from `T` to `U` which are both types that the struct
-takes. An [unsized type][1] is any type that the compiler doesn't know the
-length or alignment of at compile time. Any struct containing an unsized type
-is also unsized.
+`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
+like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
+is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
+trait.
 
-`CoerceUnsized` only allows for coercion from a structure with a single
-unsized type field to another struct with a single unsized type field.
-In fact Rust only allows for a struct to have one unsized type in a struct
-and that unsized type must be the last field in the struct. So having two
-unsized types in a single struct is not allowed by the compiler. To fix this
-use only one field containing an unsized type in the struct and then use
-multiple structs to manage each unsized type field you need.
+If the struct has multiple fields that must be unsized, then the compiler has no
+way to generate a valid implementation of `CoerceUnsized` or `DispatchFromDyn`.
 
-Example:
-
-```
-#![feature(coerce_unsized)]
-use std::ops::CoerceUnsized;
-
-struct Foo<T: ?Sized> {
-    a: i32,
-    b: T,
-}
-
-impl <T, U> CoerceUnsized<Foo<U>> for Foo<T>
-    where T: CoerceUnsized<U> {}
-
-fn coerce_foo<T: CoerceUnsized<U>, U>(t: T) -> Foo<U> {
-    Foo { a: 12i32, b: t } // we use coercion to get the `Foo<U>` type we need
-}
-```
-
-[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
+Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
+like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
+that they are pointing at.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0376.md b/compiler/rustc_error_codes/src/error_codes/E0376.md
index 50de15bd30f..5b564ec22fc 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0376.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0376.md
@@ -1,8 +1,11 @@
-`CoerceUnsized` was implemented on something that isn't a struct.
+#### Note: this error code is no longer emitted by the compiler.
+
+`CoerceUnsized` or `DispatchFromDyn` was implemented between two types that
+are not structs.
 
 Erroneous code example:
 
-```compile_fail,E0376
+```compile_fail,E0377
 #![feature(coerce_unsized)]
 use std::ops::CoerceUnsized;
 
@@ -14,33 +17,4 @@ struct Foo<T: ?Sized> {
 impl<T, U> CoerceUnsized<U> for Foo<T> {}
 ```
 
-`CoerceUnsized` can only be implemented for a struct. Unsized types are
-already able to be coerced without an implementation of `CoerceUnsized`
-whereas a struct containing an unsized type needs to know the unsized type
-field it's containing is able to be coerced. An [unsized type][1]
-is any type that the compiler doesn't know the length or alignment of at
-compile time. Any struct containing an unsized type is also unsized.
-
-[1]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait
-
-The `CoerceUnsized` trait takes a struct type. Make sure the type you are
-providing to `CoerceUnsized` is a struct with only the last field containing an
-unsized type.
-
-Example:
-
-```
-#![feature(coerce_unsized)]
-use std::ops::CoerceUnsized;
-
-struct Foo<T> {
-    a: T,
-}
-
-// The `Foo<U>` is a struct so `CoerceUnsized` can be implemented
-impl<T, U> CoerceUnsized<Foo<U>> for Foo<T> where T: CoerceUnsized<U> {}
-```
-
-Note that in Rust, structs can only contain an unsized type if the field
-containing the unsized type is the last and only unsized type field in the
-struct.
+`CoerceUnsized` or `DispatchFromDyn` can only be implemented between structs.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0377.md b/compiler/rustc_error_codes/src/error_codes/E0377.md
index b1d36406332..cd2b26260a8 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0377.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0377.md
@@ -1,5 +1,5 @@
-The trait `CoerceUnsized` may only be implemented for a coercion between
-structures with the same definition.
+`CoerceUnsized` or `DispatchFromDyn` may only be implemented between structs
+of the same type.
 
 Example of erroneous code:
 
@@ -20,10 +20,15 @@ pub struct Bar<T: ?Sized> {
 impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
 ```
 
-When attempting to implement `CoerceUnsized`, the `impl` signature must look
-like: `impl CoerceUnsized<Type<U>> for Type<T> where T: CoerceUnsized<U>`;
-the *implementer* and *`CoerceUnsized` type parameter* must be the same
-type. In this example, `Bar` and `Foo` (even though structurally identical)
-are *not* the same type and are rejected. Learn more about the `CoerceUnsized`
-trait and DST coercion in
-[the `CoerceUnsized` docs](../std/ops/trait.CoerceUnsized.html).
+`CoerceUnsized` is used to coerce structs that have a field that can be unsized,
+like a custom `MyBox<T>` being unsized to `MyBox<dyn Trait>`. `DispatchFromDyn`
+is used to dispatch from `MyBox<dyn Trait>` to `MyBox<Self>` in a dyn-compatible
+trait.
+
+The compiler cannot support coercions between structs of different types, so
+a valid implementation of `CoerceUnsized` or `DispatchFromDyn` should be
+implemented between the same struct with different generic parameters.
+
+Note that `CoerceUnsized` and `DispatchFromDyn` is mainly used by smart pointers
+like `Box`, `Rc` and `Arc` to be able to mark that they can coerce unsized types
+that they are pointing at.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0802.md b/compiler/rustc_error_codes/src/error_codes/E0802.md
new file mode 100644
index 00000000000..59061ff0435
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0802.md
@@ -0,0 +1,94 @@
+The target of `derive(CoercePointee)` macro has inadmissible specification for
+a meaningful use.
+
+Erroneous code examples:
+
+The target data is not a `struct`.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+enum NotStruct<'a, T: ?Sized> {
+    Variant(&'a T),
+}
+```
+
+The target data has a layout that is not transparent, or `repr(transparent)`
+in other words.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+struct NotTransparent<'a, #[pointee] T: ?Sized> {
+    ptr: &'a T,
+}
+```
+
+The target data has no data field.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+#[repr(transparent)]
+struct NoField<'a, #[pointee] T: ?Sized> {}
+```
+
+The target data is not generic over any data, or has no generic type parameter.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+#[repr(transparent)]
+struct NoGeneric<'a>(&'a u8);
+```
+
+The target data has multiple generic type parameters, but none is designated as
+a pointee for coercion.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+#[repr(transparent)]
+struct AmbiguousPointee<'a, T1: ?Sized, T2: ?Sized> {
+    a: (&'a T1, &'a T2),
+}
+```
+
+The target data has multiple generic type parameters that are designated as
+pointees for coercion.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+#[repr(transparent)]
+struct TooManyPointees<
+    'a,
+    #[pointee] A: ?Sized,
+    #[pointee] B: ?Sized>
+((&'a A, &'a B));
+```
+
+The type parameter that is designated as a pointee is not marked `?Sized`.
+
+```compile_fail,E0802
+#![feature(coerce_pointee)]
+use std::marker::CoercePointee;
+#[derive(CoercePointee)]
+#[repr(transparent)]
+struct NoMaybeSized<'a, #[pointee] T> {
+    ptr: &'a T,
+}
+```
+
+In summary, the `CoercePointee` macro demands the type to be a `struct` that is
+generic over at least one type or over more types, one of which is marked with
+`#[pointee]`, and has at least one data field and adopts a `repr(transparent)`
+layout.
+The only generic type or the type marked with `#[pointee]` has to be also
+marked as `?Sized`.
diff --git a/compiler/rustc_error_codes/src/error_codes/E0803.md b/compiler/rustc_error_codes/src/error_codes/E0803.md
new file mode 100644
index 00000000000..4c022688a2d
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0803.md
@@ -0,0 +1,46 @@
+A trait implementation returns a reference without an
+explicit lifetime linking it to `self`.
+It commonly arises in generic trait implementations
+requiring explicit lifetime bounds.
+
+Erroneous code example:
+
+```compile_fail,E0803
+trait DataAccess<T> {
+    fn get_ref(&self) -> T;
+}
+
+struct Container<'a> {
+    value: &'a f64,
+}
+
+// Attempting to implement reference return
+impl<'a> DataAccess<&f64> for Container<'a> {
+    fn get_ref(&self) -> &f64 { // Error: Lifetime mismatch
+        self.value
+    }
+}
+```
+
+The trait method returns &f64 requiring an independent lifetime
+The struct Container<'a> carries lifetime parameter 'a
+The compiler cannot verify if the returned reference satisfies 'a constraints
+Solution
+Explicitly bind lifetimes to clarify constraints:
+```
+// Modified trait with explicit lifetime binding
+trait DataAccess<'a, T> {
+    fn get_ref(&'a self) -> T;
+}
+
+struct Container<'a> {
+    value: &'a f64,
+}
+
+// Correct implementation (bound lifetimes)
+impl<'a> DataAccess<'a, &'a f64> for Container<'a> {
+    fn get_ref(&'a self) -> &'a f64 {
+        self.value
+    }
+}
+```
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 0a30bdb48a0..098ca42be2b 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -545,6 +545,8 @@ E0798: 0798,
 E0799: 0799,
 E0800: 0800,
 E0801: 0801,
+E0802: 0802,
+E0803: 0803,
         );
     )
 }