Do not discern between statements with and without semicolon after lowering to HIR - #61753
petrochenkov wants to merge 2 commits into
Conversation
|
@bors try |
|
⌛ Trying commit bf0b6aaf8574b194bdf95fc698dd6508e02278f9 with merge af22dfc7f56a5057c6b6120a65c74e7b6c1530af... |
|
cc @rust-lang/lang |
There was a problem hiding this comment.
| /// An expression statement. | |
| /// An expression statement (may have any type). |
There was a problem hiding this comment.
Can you update the comment that outlines the desugaring at the top of the match arm?
There was a problem hiding this comment.
(T-Lang: N.B. this removes the expectation that { expr } : () and so therefore:
{ core::default::Default::default() }
1;may stop compiling (crater will find out).
We could add inference defaulting to () if that is desirable.
Huh, that's the behavior I would've expected-- my intuition was that intermediate statements should always be of type |
|
Yeah, the intention is that |
|
☀️ Try build successful - checks-travis |
|
@craterbot run mode=check-only |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🎉 Experiment
|
|
Hmm, all the errors are in the "does not live long enough" category, rather than regressed type inference. This is due to changes in for x in xs {
doit()
}
=>
for x in xs {
doit();
}(No other block or loop constructions do that.) UPDATE: It's even worse - I'll revert this part and you'll see what effect it has on tests. |
| fn main() { | ||
| for x in 0..3 { | ||
| x //~ ERROR mismatched types | ||
| x |
There was a problem hiding this comment.
x no longer needs to unify with (), so it's no longer an error.
| // Check that the tail statement in the body unifies with something | ||
| for _ in 0..3 { | ||
| unsafe { std::mem::uninitialized() } | ||
| unsafe { std::mem::uninitialized() } //~ ERROR type annotations needed |
There was a problem hiding this comment.
unsafe { std::mem::uninitialized() } no longer needs to unify with (), so it cannot infer its type.
|
Updated with |
|
@petrochenkov Can you open an issue about the |
|
We discussed this in the @rust-lang/lang meeting and we agreed that the current behavior is roughly as-intended (implementation inconsistencies aside), and that this change and similar ones should go through the RFC process. |
|
Ok, this is not something important enough to go through an RFC. The |
In AST we need to discern between statements with semicolon and statements without semicolon in a block to detect the block's "trailing expression" (which may end up trailing after macro expansion, but start somewhere in the middle of the block, see the in-progress issue #61733).
After the trailing expression is detected during lowering to HIR, the distinction is no longer necessary...
... with exception of one surprising corner case that I discovered today:
Apparently semicolon-less expression in the middle of a block must unify with
()for some reason.The reason is unclear to me, so this PR removes this special case and unifies
StmtKind::ExprandStmtKind::Semiin HIR.r? @nikomatsakis