Mark yields after visiting subexpressions. Never ignore yields for scopes in bindings.

This commit is contained in:
John Kåre Alsaker 2017-09-08 08:52:03 +02:00 committed by Ariel Ben-Yehuda
parent 0bf7b55158
commit 0bb3dc19bf
3 changed files with 18 additions and 39 deletions

View File

@ -822,23 +822,6 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
// record_superlifetime(new_cx, expr.callee_id);
}
hir::ExprYield(..) => {
// Mark this expr's scope and all parent scopes as containing `yield`.
let mut scope = Scope::Node(expr.hir_id.local_id);
loop {
visitor.scope_tree.yield_in_scope.insert(scope,
(expr.span, visitor.expr_count));
// Keep traversing up while we can.
match visitor.scope_tree.parent_map.get(&scope) {
// Don't cross from closure bodies to their parent.
Some(&Scope::CallSite(_)) => break,
Some(&superscope) => scope = superscope,
None => break
}
}
}
_ => {}
}
}
@ -854,6 +837,23 @@ fn resolve_expr<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, expr:
_ => intravisit::walk_expr(visitor, expr)
}
if let hir::ExprYield(..) = expr.node {
// Mark this expr's scope and all parent scopes as containing `yield`.
let mut scope = Scope::Node(expr.hir_id.local_id);
loop {
visitor.scope_tree.yield_in_scope.insert(scope,
(expr.span, visitor.expr_count));
// Keep traversing up while we can.
match visitor.scope_tree.parent_map.get(&scope) {
// Don't cross from closure bodies to their parent.
Some(&Scope::CallSite(_)) => break,
Some(&superscope) => scope = superscope,
None => break
}
}
}
visitor.cx = prev_cx;
}

View File

@ -36,7 +36,7 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
let live_across_yield = scope.map_or(Some(DUMMY_SP), |s| {
self.region_scope_tree.yield_in_scope(s).and_then(|(span, expr_count)| {
// Check if the span in the region comes after the expression
if expr_count > self.expr_count {
if expr.is_none() || expr_count >= self.expr_count {
Some(span)
} else {
None

View File

@ -1,21 +0,0 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(generators, generator_trait, conservative_impl_trait)]
use std::ops::Generator;
fn bar(baz: String) -> impl Generator<Yield=(), Return=()> {
move || {
yield drop(&baz);
}
}
fn main() {}