Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Here's what Rust's compiler actually does today:

https://doc.rust-lang.org/nightly/nightly-rustc/rustc_mir_bu...

Rust lets you say either "There are four specific possible Clowns, and I want everybody to explicitly deal with that" or you can write #[non_exhaustive] to say "There are several Clowns, right now I defined four of them, but maybe I'll add more some day" in which case you are allowed to only write code for those four Clowns, but everybody else is obliged by the compiler to handle the case with more Clowns than that since they can't depend on there only being four, and they have no idea how to name the additional ones that don't yet exist.

So, a compiler that just punts is not a correct Rust compiler. It needs to do this analysis or it's compiling a different less useful language.

In the real world the (default) exhaustive case is great for types that reflect some truth about the world being modelled, where you really do mean that all the code relying on this enumerated type should refuse to compile and needs re-engineering if your list is subsequently discovered not to really be exhaustive. Teapot not withstanding, there are definitely only five PlatonicSolids, such as Tetrahedron and Cube. The non-exhaustive case is great for types that reflect a truth you know or strongly suspect will change and everybody using your system needs to be prepared for that up front. In 2016 the enumerated list of US FederalHolidays didn't need Juneteenth, but in 2021 it does, we don't want random code to blow up because it had never imagined Congress would make new ones.



Sure. But a naive compiler whose only purpose is to stomp out a poorly optimized executable can safely ignore that annotation, right?


You could instead require everything to be treated as non-exhaustive in your cheap compiler. This means it would reject correct Rust code that explicitly handles each of the five PlatonicSolids differently, because that code lacks a way to handle a sixth (non-existent) PlatonicSolid.

You can't just go "Eh, shrug emoji" without deciding what happens when you don't match.

Suppose you silently treat the first (or last) handled case as the default, so I can write code that only handles Cubes and unlike the real Rust compiler your naive compiler spits out a program. But wait, now what happens for a Tetrahedron? I defined Cubes to have a 32-bit floating point size, but for whatever reason Tetrahedrons have a 16-bit integer length instead. Does your compiler just try to treat the 16-bit integer as a 32-bit floating point number since it assumes this was a Cube?


Yes, that annotation doesn't affect the codegen of a correct program (optimizations aside).


No, because checking that it is exhaustive is required by the language definition.

It's not just not optimized, it's wrong.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: