reference icon indicating copy to clipboard operation
reference copied to clipboard

if_expr.md: Outline behavior regarding rustc E0317

Open daerich opened this issue 4 years ago • 7 comments

Change 2nd substatement from being factual to being a possibility to hint at the following behavior:

fn main() {
let ex0 = if true {42;}; /* Passes, value is () */
let ex1 = if false {42;}; /* ditto */ 
let ex2 = if false {()}; /* Passes also */
let ex3 = if true {42}; /* Error E0317 */
}

daerich avatar Sep 09 '21 14:09 daerich

Thanks for the contribution! I'm having a hard time trying to understand either the original or the proposed changes, and was wondering if you could maybe clarify or work towards improving this.

I'm not sure I follow the original "() if no block is evaluated". I'm guessing that is trying to cover your let ex2 = if false {()}; example, where no else blocks were technically evaluated in that example.

I'm not quite following the connection to the final expression of the blocks here. Either the block is evaluated are it isn't, so I would not expect there to be a significance here. Can you say more about why this is adding that qualification?

A detail that I think is missing here is that if there is no else block, the type of the blocks must coerce to (). I think that covers the ex3 example you have.

ehuss avatar Sep 14 '21 23:09 ehuss

First off: Thanks for taking the time to review my proposed changes!

I intially wanted to incoporate two findings, when doing arbitrary tests with the compiler:

  • Firstly, when the final operand expression is present in the if- block, even if it surely will execute ( like "ex3") the compiler is certainly very conservative and coerces the return type to unit (): Then the original sentence in the reference is false, stating that it only does this coercion, when no block is executed. But ex3 would be executed, even though it is a laboratory example. A (useless) loophole in the reference, if you will...

  • Secondly the first finding can be disproven if there is no final operand expression to evaluate to (ex0,ex1): Then my constructed corner case passes (type) analysis ,even if its condition operand is false and returns unit () to its caller.

So I came to the conclusion that:

  • If the to be compiled code has a final condition operand it must cover all cases in its subexpressions to have it return the value of the desired type, regardless of the exact circumstances of the whole if expression(if true, should always return as intended). Otherwise an E0317 is raised (and the return type would be unit).
  • On the other hand if you don't return anything over the final operand in block expression route, the compiler doesn't, and need not care, about the exact circumstances of the if-expression, as it will be unit () anyways in Rusts type theory, and lets the code pass. This seems to be also the case for ex2.

Since I am in no way affiliated with compiler and language development I can only speculate, that the Error E0317 and the behavior regarding types and the if- expression is about declared intent, especially since ex2 passes, at least for now. So changed the factual statement "if no block is evaluated" to a possibility "can (possibly) be evaluated" to reflect finding no. 1 and added "not any block's final operand expression" in light of my second finding.

I hope my intentions were clarified, I honestly tried :).

daerich avatar Sep 16 '21 15:09 daerich

Thanks for trying to clarify. I think this can be fixed perhaps by changing the sentence to something like the following:

If there is no else block, the type of all the blocks must coerce to (). An if expression evaluates to the same value as the executed block. If no blocks are executed, as in the case where there is no else block and the condition is false, the if expression evaluates to ().

From your examples, I think this should cover them:

  • ex0: All blocks must be () which this is.
  • ex1: All blocks must be (), and the if expression evaluates to () because no blocks were executed.
  • ex2: Pretty much the same as ex1.
  • ex3: This is an error because not all blocks can coerce their types to () (42 in this case).

ehuss avatar Sep 26 '21 19:09 ehuss

@daerich Just checking in to see if you are still interested in working on clarifying this? Were there any questions you had from the last suggestion?

ehuss avatar Nov 29 '21 23:11 ehuss

Hey @ehuss , sorry for my absence lately but I am very busy with my CS Studies atm. Sure, I am still interested in clarification of that behavior. I will look into that matter around Christmas time, when I will hopefully have time to do other work than my academic assignments.

daerich avatar Dec 04 '21 14:12 daerich