Mark yields after visiting subexpressions. Never ignore yields for scopes in bindings.
This commit is contained in:
parent
0bf7b55158
commit
0bb3dc19bf
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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() {}
|
Loading…
Reference in New Issue
Block a user