struct Goose;
let x = Goose; // The variable x has type Goose, but also value Goose, the only value of that type
The choice to underscore that Rust's unit types have size zero is to contrast with languages like C or C++ where these types, which don't need representing, must nevertheless take up a whole byte of storage and it's just wasted.But what we're talking about here are empty types. In Rust we'd write this:
enum Donkey {}
// We can't make any variables with the Donkey type, because there are no values of this type and a variable needs a valueRust's core::convert::Infallible is such a type, representing in that case the error type for conversions which have no errors. For example, we can try to convert most numeric types into a 16-bit unsigned type, and obviously most of them can fail because your value was too big or negative or whatever. u16 however obviously never fails, the conversion is a no-op, nevertheless it would be stupid if we can't write generic code to convert it - so of course we can, and if we wrote generic error handling code, that code is dead for the u16 case, we can't fail, the use of empty types here justifies the compiler saying OK, that code is dead, don't emit it. Likewise converting u8 to u16 can't fail - although it's slightly more than a no-op in some sense - and so again the error handling is dead code.
io.concurrent(foo, .{});
where foo's return type is `error{foobar}!noreturn`, because the compiler crashes when it tries to use that type as a std.Io.Future(T)'s struct field. Might be related or not.