Change:
When the is not the tail expression, we provide the right output. We might just have to change the order of operation when looking for additional context to print. as tail expression has the same problem. All checked, current version 1.78. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
why we don't suggest add in this case:
I believe it is because we check whether the tail expression is not a value. is never useful and people would never want it for any reason. For .
Hi, I'm new to the rust development and want to start with this issue.
you can make a comment saying to be assigned to the issue :) (so people filtering for unassigned issues to work on don't have it show up)
claim
I tried to investigate on this issue and here is a case that has the correct output: The difference between the two cases lies in: The correct case is parsed into nodes that include a node where the field is None. In contrast, in the erroneous case, the field of the node is not None, which is the content of filed in the of the correct case. More details are available in this gist: So the wrong case keeps iterating until node is the , which leads to the return here: The correct case has a early return with None here: Finally, in the function , the wrong case enters into the if condition unlike the other one: I'm uncertain about where to start with a fix. Should I modify the structure of this node or introduce some limitations? I've drafted a potential fix here: , but it's tailored specifically to this case. I'd appreciate any thoughts or feedback. Thanks!
I believe you can just modify to additionally check whether the node is an else-less (adding an arm to the match like ) with no adverse effects, but you'll have to try it out to see if there's any covered use of that expects that case to continue climbing the hir tree. Just run and that will modify the files to see the effects of your change. The other case: I think is ok. It could do with a more targeted error that will be more involved (to emit a single error instead of multiple), but I wouldn't consider it in scope for this ticket.
Thanks for you kind and clear instructions! I've ran and it turned out that this change has no effect on the other cases. Considering the other case you mentioned, in my opinion, I think it may be better to emit multiple errors. Here is a case: In this case, would aggregating errors into a single message make the correction less clear? I think the multiple errors might be a good reminder for users to fix errors in several specific branches. Maybe I misunderstand your meaning about the single error. Sorry for that.
Yeah, you're right. The only case where emitting a single E0308 error for this is when the expected type of the whole expression is one and all of the arms are of the same type.

Discussion:
Node::Block(Block { expr: None, .. }) => return None, // The current node is not the tail expression of its parent. Node::Block(Block { expr: Some(e), .. }) if hir_id != e.hir_id => return None, <ins> Node::Block(Block { expr: Some(e), ..}) if matches!(e.kind, ExprKind::If(_, _, None)) => return None, </ins> _ => {} } }

<ins> fn main() { if true { "" //~ ERROR mismatched types [E0308] } } </ins>

<ins> error[E0308]: mismatched types --> $DIR/tail-expr-if-as-return.rs:3:9 | LL | /     if true { LL | |         "" | |         ^^ expected `()`, found `&str` LL | |     } | |_____- expected this to be `()` error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0308`. </ins>