diff --git a/src/librustc/ich/impls_mir.rs b/src/librustc/ich/impls_mir.rs index 63100f4c11a..9b9a6a0273e 100644 --- a/src/librustc/ich/impls_mir.rs +++ b/src/librustc/ich/impls_mir.rs @@ -27,6 +27,7 @@ impl_stable_hash_for!(struct mir::LocalDecl<'tcx> { ty, name, source_info, + internal, is_user_variable }); impl_stable_hash_for!(struct mir::UpvarDecl { debug_name, by_ref }); diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a255221c871..7b71bc0e678 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -411,6 +411,10 @@ pub struct LocalDecl<'tcx> { /// True if this corresponds to a user-declared local variable. pub is_user_variable: bool, + /// True if this an internal local. + /// Such locals are not checked against the legal types in a generator. + pub internal: bool, + /// Type of this local. pub ty: Ty<'tcx>, @@ -436,6 +440,23 @@ impl<'tcx> LocalDecl<'tcx> { span, scope: ARGUMENT_VISIBILITY_SCOPE }, + internal: false, + is_user_variable: false + } + } + + /// Create a new `LocalDecl` for a internal temporary. + #[inline] + pub fn new_internal(ty: Ty<'tcx>, span: Span) -> Self { + LocalDecl { + mutability: Mutability::Mut, + ty, + name: None, + source_info: SourceInfo { + span, + scope: ARGUMENT_VISIBILITY_SCOPE + }, + internal: true, is_user_variable: false } } @@ -452,6 +473,7 @@ impl<'tcx> LocalDecl<'tcx> { span, scope: ARGUMENT_VISIBILITY_SCOPE }, + internal: false, name: None, // FIXME maybe we do want some name here? is_user_variable: false } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 325c87fded6..234583f7d79 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -654,6 +654,7 @@ macro_rules! make_mir_visitor { ref $($mutability)* ty, name: _, ref $($mutability)* source_info, + internal: _, is_user_variable: _, } = *local_decl; diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 54f285480ab..702fc89fa12 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -712,6 +712,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { ty: var_ty.clone(), name: Some(name), source_info: source_info, + internal: false, is_user_variable: true, }); self.var_indices.insert(var_id, var); diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index d8d6c398b51..7c65d50269f 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -521,6 +521,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { span: pattern.map_or(self.fn_span, |pat| pat.span) }, name: name, + internal: false, is_user_variable: false, }); } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index bc04be18ac6..fee9ff854cd 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -128,6 +128,7 @@ fn temp_decl(mutability: Mutability, ty: Ty, span: Span) -> LocalDecl { LocalDecl { mutability, ty, name: None, source_info: SourceInfo { scope: ARGUMENT_VISIBILITY_SCOPE, span }, + internal: false, is_user_variable: false } } diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs index f5a2b1b974c..308a48677e5 100644 --- a/src/librustc_mir/transform/elaborate_drops.rs +++ b/src/librustc_mir/transform/elaborate_drops.rs @@ -314,7 +314,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> { let patch = &mut self.patch; debug!("create_drop_flag({:?})", self.mir.span); self.drop_flags.entry(index).or_insert_with(|| { - patch.new_temp(tcx.types.bool, span) + patch.new_internal(tcx.types.bool, span) }); } diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 603e9d1849f..524b76b2e6b 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -263,6 +263,7 @@ fn replace_result_variable<'tcx>(ret_ty: Ty<'tcx>, ty: ret_ty, name: None, source_info, + internal: false, is_user_variable: false, }; let new_ret_local = Local::new(mir.local_decls.len()); @@ -314,7 +315,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let allowed = tcx.erase_regions(&interior.as_slice()); for (local, decl) in mir.local_decls.iter_enumerated() { - if !live_locals.contains(&local) { + if !live_locals.contains(&local) || decl.internal { continue; } if !allowed.contains(&decl.ty) { @@ -340,6 +341,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: unit, name: None, source_info, + internal: false, is_user_variable: false, }; remap.insert(local, (var.ty, upvar_len + 1 + idx)); @@ -482,6 +484,7 @@ fn generate_drop<'a, 'tcx>( ty: tcx.mk_nil(), name: None, source_info, + internal: false, is_user_variable: false, }; @@ -496,6 +499,7 @@ fn generate_drop<'a, 'tcx>( }), name: None, source_info, + internal: false, is_user_variable: false, }; diff --git a/src/librustc_mir/util/patch.rs b/src/librustc_mir/util/patch.rs index ac121131eb9..3cf78584067 100644 --- a/src/librustc_mir/util/patch.rs +++ b/src/librustc_mir/util/patch.rs @@ -101,6 +101,13 @@ impl<'tcx> MirPatch<'tcx> { Local::new(index as usize) } + pub fn new_internal(&mut self, ty: Ty<'tcx>, span: Span) -> Local { + let index = self.next_local; + self.next_local += 1; + self.new_locals.push(LocalDecl::new_internal(ty, span)); + Local::new(index as usize) + } + pub fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock { let block = BasicBlock::new(self.patch_map.len()); debug!("MirPatch: new_block: {:?}: {:?}", block, data); diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 148cf0ddbff..f116620388f 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -66,9 +66,6 @@ pub fn find_interior<'a, 'gcx, 'tcx>(fcx: &'a FnCtxt<'a, 'gcx, 'tcx>, }; intravisit::walk_body(&mut visitor, body); - // FIXME: Drop elaboration can insert bool types in the generator - visitor.types.insert(fcx.tcx.types.bool); - // Deduplicate types let set: FxHashSet<_> = visitor.types.into_iter() .map(|t| fcx.resolve_type_vars_if_possible(&t))