diff options
| author | Boxy <rust@boxyuwu.dev> | 2025-02-25 21:27:44 +0000 |
|---|---|---|
| committer | Boxy <rust@boxyuwu.dev> | 2025-02-25 21:27:44 +0000 |
| commit | d9683df7c2f6d4141b1321e27635d2ce3167eaa4 (patch) | |
| tree | dce0d46d1b7d624ec9b9b09b2c1854f6245a5ff4 /compiler/rustc_error_codes/src | |
| parent | 46392d1661540e256fd9573d8f06c2784a58c983 (diff) | |
| parent | 4ecd70ddd1039a3954056c1071e40278048476fa (diff) | |
| download | rust-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.md | 14 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0374.md | 53 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0375.md | 47 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0376.md | 38 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0377.md | 23 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0802.md | 94 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0803.md | 46 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/lib.rs | 2 |
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, ); ) } |
