[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)