[HN Gopher] Flavors of enums with Rust bindgen
___________________________________________________________________
Flavors of enums with Rust bindgen
Author : mdaverde
Score : 22 points
Date : 2022-06-13 15:05 UTC (7 hours ago)
(HTM) web link (www.mdaverde.com)
(TXT) w3m dump (www.mdaverde.com)
| WhatIsDukkha wrote:
| If you just want to do this on an enum within Rust, as I did just
| this morning, the strum crate is very useful -
|
| https://stackoverflow.com/posts/50879764/revisions
| anderskaseorg wrote:
| Might be worth copying the caveat about UB on out-of-range values
| into the rustified_non_exhaustive_enum section. Otherwise someone
| who isn't familiar with #[non_exhaustive] might incorrectly
| assume that it removes this UB.
| Gadiguibou wrote:
| I'm not familiar with #[non_exhaustive]. Why's there still UB
| when specifying it?
| gilnaa wrote:
| You put #[non_exhaustive] on a enum in Rust to force users
| matching on it to handle an "else"/"default" case, so that
| you can add more variants to this enum in the future without
| breaking their code.
|
| It doesn't mean that the enum itself is non exhaustive: at
| any point in time when enum is defined, it defines all of its
| variants and any other value is still UB.
| tialaramex wrote:
| Right, the purpose of this annotation is to prevent humans
| from writing code that's going to break in the future _not_
| to prevent the compiler from optimising the code it sees in
| front of it right now today. Let 's provide a little
| example.
|
| Suppose I've written a library with a USFederalHoliday
| type, it's 2018 when I ship version 1, and so of course my
| library doesn't have Juneteenth because that's not a
| Federal Holiday. But I am aware that over the history of
| the US, new holidays get created, and so I add the
| annotation non_exhaustive. A program you wrote using this
| type in 2019 might have matches for NewYears, LaborDay,
| VeteransDay and all the others but because of
| non_exhaustive you're obliged to write a clause handling
| "other" possibilities, even though at the time there aren't
| any.
|
| In 2021 I add Juneteenth to the enumeration, ship that as
| version 2, and _your program still compiles with the new
| version_. Juneteenth just matches the "other" case in any
| matches, Rust checked those are valid even when they were
| never used, now they're used. They might be _wrong_ of
| course, Rust can 't fix that.
|
| Now, suppose your program prints the phrase
| "Congratulations on your new holiday" to stderr only if the
| other case matches.
|
| When compiled against version 1, Rust's compiler is obliged
| to check that the syntax and semantics of your "print
| Congrats" stuff works but it is _not_ obliged to actually
| emit code which can detect such a case and actually print
| the message because it can tell, at compile time, that
| version 1 of the library actually _has_ no other cases you
| didn 't handle. The "Congratulations" message may end up
| not even compiled into the program.
|
| With version 2, the compiler can see that _now_ Juneteenth
| is a USFederalHoliday and that isn 't handled by your code,
| and so that "Congratulations" message might be used, and
| the message definitely goes in to the binary.
|
| Now, the unsafe transformation of values from a non-Rust
| library could result in unexpected bit patterns for a type
| which claims to be USFederalHoliday, but Rust's compiler
| was _never_ expecting to see such values. In _safe_ Rust
| they can 't happen and if you introduce them from unsafe
| Rust that's Undefined Behaviour. So despite the
| non_exhaustive annotation, the compiler needn't ensure that
| such bit patterns do something reasonable.
___________________________________________________________________
(page generated 2022-06-13 23:01 UTC)