From 425953083de7f2decba713cabced2599334008f1 Mon Sep 17 00:00:00 2001 From: mixy1 Date: Mon, 9 Sep 2024 23:30:02 +0200 Subject: [PATCH 1/4] Update type_system.md --- src/attributes/type_system.md | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/attributes/type_system.md b/src/attributes/type_system.md index dd3ea9874..2cbe7d015 100644 --- a/src/attributes/type_system.md +++ b/src/attributes/type_system.md @@ -163,11 +163,32 @@ match message { } ``` -It's also not allowed to cast non-exhaustive types from foreign crates. +In Rust, casting non-exhaustive types from foreign crates is generally disallowed, except when dealing with enums that have no non-exhaustive variants. + +For example, the following enum can be cast because it doesn't contain any non-exhaustive variants: +```rust, ignore +#[non_exhaustive] +pub enum Example { + First, + Second +} +``` + +However, if the enum contains even a single non-exhaustive variant, casting will result in an error. Consider this modified version of the same enum: + +```rust, ignore +#[non_exhaustive] +pub enum Example { + First, + #[non_exhaustive] + Second +} +``` + ```rust, ignore -use othercrate::NonExhaustiveEnum; +use othercrate::NonExhaustiveEnumVariants; -// Cannot cast a non-exhaustive enum outside of its defining crate. +// cannot cast an enum with a non-exhaustive variant when it's defined in another crate let _ = NonExhaustiveEnum::default() as u8; ``` From 2cf703df6234351f2e27e3aaf286ccdfc925501c Mon Sep 17 00:00:00 2001 From: mixy1 Date: Mon, 9 Sep 2024 23:32:25 +0200 Subject: [PATCH 2/4] Update type_system.md with proper Enum name --- src/attributes/type_system.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/attributes/type_system.md b/src/attributes/type_system.md index 2cbe7d015..c1c0c7871 100644 --- a/src/attributes/type_system.md +++ b/src/attributes/type_system.md @@ -163,7 +163,7 @@ match message { } ``` -In Rust, casting non-exhaustive types from foreign crates is generally disallowed, except when dealing with enums that have no non-exhaustive variants. +However, casting non-exhaustive types from foreign crates is generally disallowed, except when dealing with enums that have no non-exhaustive variants. For example, the following enum can be cast because it doesn't contain any non-exhaustive variants: ```rust, ignore @@ -186,10 +186,10 @@ pub enum Example { ``` ```rust, ignore -use othercrate::NonExhaustiveEnumVariants; +use othercrate::EnumWithNonExhaustiveEnumVariants; -// cannot cast an enum with a non-exhaustive variant when it's defined in another crate -let _ = NonExhaustiveEnum::default() as u8; +// Error: cannot cast an enum with a non-exhaustive variant when it's defined in another crate +let _ = EnumWithNonExhaustiveEnumVariants::default() as u8; ``` Non-exhaustive types are always considered inhabited in downstream crates. From efdf702385be34297b949b2c3174619d79fcddfd Mon Sep 17 00:00:00 2001 From: mixy1 Date: Mon, 9 Sep 2024 23:47:47 +0200 Subject: [PATCH 3/4] Reword first sentence to be more specific. Co-authored-by: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> --- src/attributes/type_system.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/attributes/type_system.md b/src/attributes/type_system.md index c1c0c7871..f8691b30d 100644 --- a/src/attributes/type_system.md +++ b/src/attributes/type_system.md @@ -163,7 +163,7 @@ match message { } ``` -However, casting non-exhaustive types from foreign crates is generally disallowed, except when dealing with enums that have no non-exhaustive variants. +It's also not allowed to use numeric casts (`as`) on enums that contain any non-exhaustive variants. For example, the following enum can be cast because it doesn't contain any non-exhaustive variants: ```rust, ignore From 7c94f299c1d638c036db91df3e8e11c1d172f858 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 10 Sep 2024 12:19:27 -0700 Subject: [PATCH 4/4] Fixup exhaustive enum examples Examples don't need to be ignored when they compile correctly. Use the same enum name between the definition and the use. I think this helps tie to the two examples together. Don't use `default()` when default isn't derived in the example. --- src/attributes/type_system.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/attributes/type_system.md b/src/attributes/type_system.md index f8691b30d..d3ea63233 100644 --- a/src/attributes/type_system.md +++ b/src/attributes/type_system.md @@ -166,7 +166,8 @@ match message { It's also not allowed to use numeric casts (`as`) on enums that contain any non-exhaustive variants. For example, the following enum can be cast because it doesn't contain any non-exhaustive variants: -```rust, ignore + +```rust #[non_exhaustive] pub enum Example { First, @@ -176,20 +177,21 @@ pub enum Example { However, if the enum contains even a single non-exhaustive variant, casting will result in an error. Consider this modified version of the same enum: -```rust, ignore +```rust #[non_exhaustive] -pub enum Example { +pub enum EnumWithNonExhaustiveVariants { First, #[non_exhaustive] Second } ``` -```rust, ignore -use othercrate::EnumWithNonExhaustiveEnumVariants; + +```rust,ignore +use othercrate::EnumWithNonExhaustiveVariants; // Error: cannot cast an enum with a non-exhaustive variant when it's defined in another crate -let _ = EnumWithNonExhaustiveEnumVariants::default() as u8; +let _ = EnumWithNonExhaustiveVariants::First as u8; ``` Non-exhaustive types are always considered inhabited in downstream crates.