diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index e277f40a26d9..3d5de5579f0f 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -442,11 +442,15 @@ for mir::AggregateKind<'tcx> { substs.hash_stable(hcx, hasher); active_field.hash_stable(hcx, hasher); } - mir::AggregateKind::Closure(def_id, ref substs) | - mir::AggregateKind::Generator(def_id, ref substs) => { + mir::AggregateKind::Closure(def_id, ref substs) => { def_id.hash_stable(hcx, hasher); substs.hash_stable(hcx, hasher); } + mir::AggregateKind::Generator(def_id, ref substs, ref interior) => { + def_id.hash_stable(hcx, hasher); + substs.hash_stable(hcx, hasher); + interior.hash_stable(hcx, hasher); + } } } } diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 20e74f47c9e2..0d3629a8e5fe 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -21,7 +21,7 @@ use rustc_data_structures::control_flow_graph::ControlFlowGraph; use hir::def::CtorKind; use hir::def_id::DefId; use ty::subst::{Subst, Substs}; -use ty::{self, AdtDef, ClosureSubsts, Region, Ty}; +use ty::{self, AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior}; use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use util::ppaux; use rustc_back::slice; @@ -1260,7 +1260,7 @@ pub enum AggregateKind<'tcx> { /// number and is present only for union expressions. Adt(&'tcx AdtDef, usize, &'tcx Substs<'tcx>, Option), Closure(DefId, ClosureSubsts<'tcx>), - Generator(DefId, ClosureSubsts<'tcx>), + Generator(DefId, ClosureSubsts<'tcx>, GeneratorInterior<'tcx>), } #[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)] @@ -1423,7 +1423,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { } }), - AggregateKind::Generator(def_id, _) => ty::tls::with(|tcx| { + AggregateKind::Generator(def_id, _, _) => ty::tls::with(|tcx| { if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { let name = format!("[generator@{:?}]", tcx.hir.span(node_id)); let mut struct_fmt = fmt.debug_struct(&name); @@ -1892,8 +1892,8 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { AggregateKind::Adt(def, v, substs.fold_with(folder), n), AggregateKind::Closure(id, substs) => AggregateKind::Closure(id, substs.fold_with(folder)), - AggregateKind::Generator(id, substs) => - AggregateKind::Generator(id, substs.fold_with(folder)), + AggregateKind::Generator(id, substs, interior) => + AggregateKind::Generator(id, substs.fold_with(folder), interior.fold_with(folder)), }; Aggregate(kind, fields.fold_with(folder)) } @@ -1920,7 +1920,8 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> { AggregateKind::Tuple => false, AggregateKind::Adt(_, _, substs, _) => substs.visit_with(visitor), AggregateKind::Closure(_, substs) => substs.visit_with(visitor), - AggregateKind::Generator(_, substs) => substs.visit_with(visitor), + AggregateKind::Generator(_, substs, interior) => substs.visit_with(visitor) || + interior.visit_with(visitor), }) || fields.visit_with(visitor) } } diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 12588edbea9c..14c53ee2dd78 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -202,13 +202,8 @@ impl<'tcx> Rvalue<'tcx> { AggregateKind::Closure(did, substs) => { tcx.mk_closure_from_closure_substs(did, substs) } - AggregateKind::Generator(did, substs) => { - let node_id = tcx.hir.as_local_node_id(did).unwrap(); - let interior = *tcx.typeck_tables_of(did) - .generator_interiors - .get(&node_id) - .unwrap(); - tcx.mk_generator(did, substs, interior.subst(tcx, substs.substs)) + AggregateKind::Generator(did, substs, interior) => { + tcx.mk_generator(did, substs, interior) } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 8cc5b6cab116..30ffa73019c9 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -11,7 +11,7 @@ use middle::const_val::ConstVal; use hir::def_id::DefId; use ty::subst::Substs; -use ty::{ClosureSubsts, Region, Ty}; +use ty::{ClosureSubsts, Region, Ty, GeneratorInterior}; use mir::*; use rustc_const_math::ConstUsize; use syntax_pos::Span; @@ -226,6 +226,12 @@ macro_rules! make_mir_visitor { self.super_closure_substs(substs); } + fn visit_generator_interior(&mut self, + interior: & $($mutability)* GeneratorInterior<'tcx>, + _: Location) { + self.super_generator_interior(interior); + } + fn visit_const_val(&mut self, const_val: & $($mutability)* ConstVal, _: Location) { @@ -570,9 +576,11 @@ macro_rules! make_mir_visitor { self.visit_closure_substs(closure_substs, location); } AggregateKind::Generator(ref $($mutability)* def_id, - ref $($mutability)* closure_substs) => { + ref $($mutability)* closure_substs, + ref $($mutability)* interior) => { self.visit_def_id(def_id, location); self.visit_closure_substs(closure_substs, location); + self.visit_generator_interior(interior, location); } } @@ -742,6 +750,10 @@ macro_rules! make_mir_visitor { fn super_substs(&mut self, _substs: & $($mutability)* &'tcx Substs<'tcx>) { } + fn super_generator_interior(&mut self, + _interior: & $($mutability)* GeneratorInterior<'tcx>) { + } + fn super_closure_substs(&mut self, _substs: & $($mutability)* ClosureSubsts<'tcx>) { } diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs index d585672d6da2..b2a386792401 100644 --- a/src/librustc_mir/build/expr/as_rvalue.rs +++ b/src/librustc_mir/build/expr/as_rvalue.rs @@ -179,12 +179,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { block.and(Rvalue::Aggregate(box AggregateKind::Tuple, fields)) } - ExprKind::Closure { closure_id, substs, upvars, generator } => { // see (*) above + ExprKind::Closure { closure_id, substs, upvars, interior } => { // see (*) above let mut operands: Vec<_> = upvars.into_iter() .map(|upvar| unpack!(block = this.as_operand(block, scope, upvar))) .collect(); - let result = if generator { + let result = if let Some(interior) = interior { // Add the state operand operands.push(Operand::Constant(box Constant { span: expr_span, @@ -193,7 +193,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { value: ConstVal::Integral(ConstInt::U32(0)), }, })); - box AggregateKind::Generator(closure_id, substs) + box AggregateKind::Generator(closure_id, substs, interior) } else { box AggregateKind::Closure(closure_id, substs) }; diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index a81103213b84..b8b69382d7d0 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -428,11 +428,11 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } - hir::ExprClosure(.., is_generator) => { + hir::ExprClosure(..) => { let closure_ty = cx.tables().expr_ty(expr); - let (def_id, substs) = match closure_ty.sty { - ty::TyClosure(def_id, substs) | - ty::TyGenerator(def_id, substs, _) => (def_id, substs), + let (def_id, substs, interior) = match closure_ty.sty { + ty::TyClosure(def_id, substs) => (def_id, substs, None), + ty::TyGenerator(def_id, substs, interior) => (def_id, substs, Some(interior)), _ => { span_bug!(expr.span, "closure expr w/o closure type: {:?}", closure_ty); } @@ -447,7 +447,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, closure_id: def_id, substs: substs, upvars: upvars, - generator: is_generator, + interior, } } diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs index ff239a2adddd..89d0260fb9f5 100644 --- a/src/librustc_mir/hair/mod.rs +++ b/src/librustc_mir/hair/mod.rs @@ -19,7 +19,7 @@ use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp}; use rustc::hir::def_id::DefId; use rustc::middle::region::CodeExtent; use rustc::ty::subst::Substs; -use rustc::ty::{self, AdtDef, ClosureSubsts, Region, Ty}; +use rustc::ty::{self, AdtDef, ClosureSubsts, Region, Ty, GeneratorInterior}; use rustc::hir; use syntax::ast; use syntax_pos::Span; @@ -239,7 +239,7 @@ pub enum ExprKind<'tcx> { closure_id: DefId, substs: ClosureSubsts<'tcx>, upvars: Vec>, - generator: bool, + interior: Option>, }, Literal { literal: Literal<'tcx>, diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 90bcc87b0c4a..651246ab4a5e 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -76,8 +76,8 @@ struct TransformVisitor<'a, 'tcx: 'a> { // The number of generator states. 0 is unresumed, 1 is poisoned. So this is initialized to 2 bb_target_count: u32, - // Map from a (which block to resume execution at, which block to use to drop the generator) to a - // genrator state + // Map from a (which block to resume execution at, which block to use to drop the generator) + // to a generator state bb_targets: HashMap<(BasicBlock, Option), u32>, // The original RETURN_POINTER local