diff --git a/code/examples/misc_10.rs b/code/examples/misc_10.rs new file mode 100644 index 0000000..eac4461 --- /dev/null +++ b/code/examples/misc_10.rs @@ -0,0 +1,16 @@ +#[repr(u32)] +enum A { + Zero, + One(), + Two {}, +} + +fn main() { + println!("{}", A::Zero as usize); + println!("{}", A::One as usize); + println!("{}", A::Two as usize); + + println!("{}", A::Zero {} as usize); + println!("{}", A::One {} as usize); + println!("{}", A::Two {} as usize); +} diff --git a/code/examples/stderr/misc_10.stderr b/code/examples/stderr/misc_10.stderr new file mode 100644 index 0000000..92f0088 --- /dev/null +++ b/code/examples/stderr/misc_10.stderr @@ -0,0 +1,13 @@ +error[E0533]: expected value, found struct variant `A::Two` + --> examples/misc_10.rs:11:20 + | +11 | println!("{}", A::Two as usize); + | ^^^^^^ not a value + | +help: you might have meant to create a new value of the struct + | +11 | println!("{}", A::Two {} as usize); + | ++ + +For more information about this error, try `rustc --explain E0533`. +error: could not compile `code` (example "misc_10") due to 1 previous error diff --git a/src/misc/10.md b/src/misc/10.md new file mode 100644 index 0000000..cc0d6e1 --- /dev/null +++ b/src/misc/10.md @@ -0,0 +1,38 @@ +# Misc 10 @m-ou-se @WaffleLapkin + +{{#include ../include/quiz-is-wip.md}} + +```rust +{{#include ../../code/examples/misc_10.rs}} +``` + +For each `println!`, say what it will print or that it won't compile. + +
+Solution + +Only `A::Two as usize` doesn't compile: + +``` +{{#include ../../code/examples/stderr/misc_10.stderr}} +``` + +Subtituting the non-compiling line with a dummy print will output something like the following: +``` +0 +98926091234224 +doesn't compile +0 +1 +2 +``` + +There are multiple potentially suprising things: + +1. You can `as`-cast an enum with non-unit variants to get its discriminant, [as long as it's fieldless](https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.coercion.fieldless). + +2. `A::One as usize` gives you the *address of the constructor function of `A::One`*, and not `A::One`'s discriminant (the latter can be gotten via `A::One() as usize`). + +3. Unit and tuple variants can be constructed with `{}` syntax. This is similar to how unit and tuple structures can also be created with `{}`. + +