# Break with value alternatives

**URL:** https://internals.rust-lang.org/t/break-with-value-alternatives/11240
**Category:** language design
**Created:** [November 5, 2019, 2:18pm UTC](https://internals.rust-lang.org/t/break-with-value-alternatives/11240 "2019-11-05T14:18:56Z")
**Posts on this page:** 1
**Showing post:** 12

<div class="post-metadata">

### Author: ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)
#### Post date: [November 5, 2019, 3:16pm UTC](https://internals.rust-lang.org/t/break-with-value-alternatives/11240/12 "2019-11-05T15:16:28Z")

</div>

On the note of `Error` type in `Result`. I see this as exactly the same problem as implementing a trait, say `Write`, and wanting to provide more meaningful errors. You just can't without some workarounds. Also, I don't think that this is a common issue, so I'm fine with pessimizing it.

> [@RE: Pre-RFC: Break with value in for/while loops](https://internals.rust-lang.org/t/re-pre-rfc-break-with-value-in-for-while-loops/11238/1):
>
> The compiler can reason about inhabitedness so you don't need to.

The compiler already has to do inhabitedness checking, so this should be fine.

Also on the note of inhabitedness, in the past there have been miscompiles when using structs that contain uninhabited types because you could do something like,

> <https://github.com/rust-lang/rust/issues/49298>
>
> When we optimized product types with uninhabited fields to be ZST, partial initi…alization was overlooked, i.e. writes to the inhabited sibling fields are allowed despite missing in the layout.
> Thankfully, it's impossible to read or borrow such fields, because the whole value must be initialized (although this may be relaxed in the future). However , the initialized fields are still dropped.
> 
> One way we could work around this is track uninhabitedness but only take advantage of it in enums.
> ( ~~I am not aware of a solution that works with~~ variant types, which I think we should keep in mind.)
> \*\*EDIT\*\*: we can disallow creating the \`enum\` from an incomplete variant. This is also required by niche optimizations because the niche slot being uninitialized would result in UB.
> \*\*EDIT2\*\*: incomplete variants might be possible today already (https://github.com/rust-lang/rust/issues/49298#issuecomment-380615281).
> 
> As an example, in debug mode, this snippet prints \`0\`, because \`x.1\` and \`y\` overlap:
> \`\`\`rust
> enum Void {}
> 
> fn main() {
> let mut x: (Void, usize);
> let y = 1;
> x.1 = 0;
> println!("{}", y)
> }
> \`\`\`
> 
> cc @nikomatsakis @nagisa

So now, all structs treat uninhabited types as normal zero-sized types, and don't inherit inhabited. Also partial initialization is prohibited.

> **[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=36bdbea07f53477015b7c0ce9a26e120)**
>
> A browser interface to the Rust compiler to experiment with the language

So type theory, while nice, doesn't completely line up with Rust.

> [@RE: Pre-RFC: Break with value in for/while loops](https://internals.rust-lang.org/t/re-pre-rfc-break-with-value-in-for-while-loops/11238/2):
>
> I was referring to people being confused over whether `()` is a top type (which it obviously isn't). I don't even remember if you participated in that issue's thread, to be honest.

I don't remember that thread at all, so probably not.

> [@RE: Pre-RFC: Break with value in for/while loops](https://internals.rust-lang.org/t/re-pre-rfc-break-with-value-in-for-while-loops/11238/2):
>
> Ouch. I mean, yes, it compiles… but you're relying on `for` being a sugar for `loop` - `match` and on the `break` from the generator implicitly converting the `!` return value to the other `break` 's type. If `for` were a primitive construct which actually enforces that `break` agree with the return type of the generator (as a good abstraction should behave), it would not work. I think it's a deficiency of this desugaring that it does.

In case you didn't know, this is how for loop desugars right now,

```rust
for $var in $into_iter {
    $code
}

```

```rust
let __iterator = IntoIterator::into_iter($into_iter);

loop {
    match Iterator::next(&mut __iterator) {
        Some($var) => { $code },
        None => break
    }
}

```

Please show how your method would desugar a for loop, because if it can't then it is more complex then generators

for loops are not primitive constructs in Rust.

---

_[View the full topic](https://internals.rust-lang.org/t/break-with-value-alternatives/11240)._
