-
Notifications
You must be signed in to change notification settings - Fork 13.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #61572 - Aaron1011:fix/generator-ref, r=varkor
Fix HIR visit order Fixes #61442 When rustc::middle::region::ScopeTree computes its yield_in_scope field, it relies on the HIR visitor order to properly compute which types must be live across yield points. In order for the computed scopes to agree with the generated MIR, we must ensure that expressions evaluated before a yield point are visited before the 'yield' expression. However, the visitor order for ExprKind::AssignOp was incorrect. The left-hand side of a compund assignment expression is evaluated before the right-hand side, but the right-hand expression was being visited before the left-hand expression. If the left-hand expression caused a new type to be introduced (e.g. through a deref-coercion), the new type would be incorrectly seen as occuring *after* the yield point, instead of before. This leads to a mismatch between the computed generator types and the MIR, since the MIR will correctly see the type as being live across the yield point. To fix this, we correct the visitor order for ExprKind::AssignOp to reflect the actual evaulation order.
- Loading branch information
Showing
4 changed files
with
146 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Regression test for broken MIR error (#61442) | ||
// Due to the two possible evaluation orders for | ||
// a '+=' expression (depending on whether or not the 'AddAssign' trait | ||
// is being used), we were failing to account for all types that might | ||
// possibly be live across a yield point. | ||
|
||
#![feature(generators)] | ||
|
||
fn foo() { | ||
let _x = static || { | ||
let mut s = String::new(); | ||
s += { yield; "" }; | ||
}; | ||
|
||
let _y = static || { | ||
let x = &mut 0; | ||
*{ yield; x } += match String::new() { _ => 0 }; | ||
}; | ||
|
||
// Please don't ever actually write something like this | ||
let _z = static || { | ||
let x = &mut 0; | ||
*{ | ||
let inner = &mut 1; | ||
*{ yield (); inner } += match String::new() { _ => 1}; | ||
yield; | ||
x | ||
} += match String::new() { _ => 2 }; | ||
}; | ||
} | ||
|
||
fn main() { | ||
foo() | ||
} |