From 9d0960a6f8fbd561b2f5d9fb54ba49d533f61832 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Wed, 5 Jun 2019 19:54:34 -0400 Subject: [PATCH] Fix HIR visit order Fixes #61442 When rustc::middle::region::ScopeTree ccomputes 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. --- src/librustc/hir/intravisit.rs | 2 +- src/test/run-pass/issues/issue-61442.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/test/run-pass/issues/issue-61442.rs diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 1777d765cc8a..05bef951ddbd 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1055,8 +1055,8 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { visitor.visit_expr(left_hand_expression) } ExprKind::AssignOp(_, ref left_expression, ref right_expression) => { + visitor.visit_expr(left_expression); visitor.visit_expr(right_expression); - visitor.visit_expr(left_expression) } ExprKind::Field(ref subexpression, ident) => { visitor.visit_expr(subexpression); diff --git a/src/test/run-pass/issues/issue-61442.rs b/src/test/run-pass/issues/issue-61442.rs new file mode 100644 index 000000000000..89d1dac08bc1 --- /dev/null +++ b/src/test/run-pass/issues/issue-61442.rs @@ -0,0 +1,12 @@ +#![feature(generators)] + +fn foo() { + let _x = static || { + let mut s = String::new(); + s += { yield; "" }; + }; +} + +fn main() { + foo() +}