Break with value alternatives

This is exactly what I have been criticising in the thread above, and the one which preceded it, so I won't repeat myself here (or my preferred solution).

1 Like

Not sure I understand this, but to be clear I was proposing that

break std::option::Option::Some(val);

and

let some_val = Some(val);
break some_val;

would all be fine too. I just don't think we need to make the break'd value magically an option.

@notriddle I think there's a line missing from your desugar

let __generator = IntoGenerator::into_generator(something);

Yes, @CAD97 was responding to me.

Your solution requires type-dependent desugarring, and this is extremely undesirable. After I noted that in my previous reply, I suggested some ways to get around this, but they were really bad ideas, as @CAD97 replied.

1 Like

I am not understanding something here. The next method of iterators already returns an Option<Self::Item>. So the compiler already must know something about the Option type, since it needs to desugar

for value in 0..10{
   do_something(value);
}

into

let mut iterator=0..10;
loop{
   match iterator.next(){
      Some(value) => do_something(value),
      None => break,
   };
}

So then what is the problem with desugarring

let x = for value in 0..10{
   if value==5 {break value+7;}
}

into

let mut iterator=0..10;
let x=loop{
   match iterator.next(){
      Some(value) => if value==5 {break Some(value+7);},
      None => break None,
   };
};

I can understand a discussion between writing break value+7 or break Some(value+7). Or you could desugar the ending branch instead to None => break Default::default().

It is just the matter of trying to keep returning () instead of Option<()> when there is no break value? If that is the problem then using Default::default() would work, since both () and Option<> have a default. If the Default trait have too much semantic, then it should possible to make a new trait for this.

The problem is break; which works today and is (so far) semantically equivalent to break ();.

With that desugaring, break; would now return an Option<()> instead of ().

Also, trait Default is not (yet) a lang item. And while I don't have any reservations with using it in the language for a closed set of known lang-item types (or, well, Option which is lang-item-by-hardcoded-path IIRC), calling it implicitly on user types is problematic.

Also also, it'd be nice to distinguish between break default(); (practically a requirement) and not breaking from the loop.

So you see we have conflicting requirements here: break (); should return Some(()), break; is required to return (), and break; and break (); are supposed to be semantically equivalent.

Because of these conflicting requirements, I think that, suboptimal as it may be, if we want break-with-value from for, it needs to be tied to a new desugaring over Generator.

6 Likes