diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 1b3416e112b..a8d007c0be2 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -624,6 +624,19 @@ impl<'tcx> TypeckResults<'tcx> { LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments } } + /// For a given closure, returns the iterator of `ty::CapturedPlace`s that are captured + /// by the closure. + pub fn closure_min_captures_flattened( + &self, + closure_def_id: DefId, + ) -> impl Iterator> { + self.closure_min_captures + .get(&closure_def_id) + .map(|closure_min_captures| closure_min_captures.values().flat_map(|v| v.iter())) + .into_iter() + .flatten() + } + pub fn upvar_capture(&self, upvar_id: ty::UpvarId) -> ty::UpvarCapture<'tcx> { self.upvar_capture_map[&upvar_id] } diff --git a/compiler/rustc_typeck/src/check/upvar.rs b/compiler/rustc_typeck/src/check/upvar.rs index 019fa78fb1e..30b4682296c 100644 --- a/compiler/rustc_typeck/src/check/upvar.rs +++ b/compiler/rustc_typeck/src/check/upvar.rs @@ -202,7 +202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // inference algorithm will reject it). // Equate the type variables for the upvars with the actual types. - let final_upvar_tys = self.final_upvar_tys(closure_hir_id); + let final_upvar_tys = self.final_upvar_tys(closure_def_id); debug!( "analyze_closure: id={:?} substs={:?} final_upvar_tys={:?}", closure_hir_id, substs, final_upvar_tys @@ -222,36 +222,33 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // Returns a list of `Ty`s for each upvar. - fn final_upvar_tys(&self, closure_id: hir::HirId) -> Vec> { + fn final_upvar_tys(&self, closure_id: DefId) -> Vec> { // Presently an unboxed closure type cannot "escape" out of a // function, so we will only encounter ones that originated in the // local crate or were inlined into it along with some function. // This may change if abstract return types of some sort are // implemented. let tcx = self.tcx; - let closure_def_id = tcx.hir().local_def_id(closure_id); self.typeck_results .borrow() - .closure_captures - .get(&closure_def_id.to_def_id()) - .iter() - .flat_map(|upvars| { - upvars.iter().map(|(&var_hir_id, _)| { - let upvar_ty = self.node_ty(var_hir_id); - let upvar_id = ty::UpvarId::new(var_hir_id, closure_def_id); - let capture = self.typeck_results.borrow().upvar_capture(upvar_id); + .closure_min_captures_flattened(closure_id) + .map(|captured_place| { + let upvar_ty = captured_place.place.ty(); + let capture = captured_place.info.capture_kind; - debug!("var_id={:?} upvar_ty={:?} capture={:?}", var_hir_id, upvar_ty, capture); + debug!( + "place={:?} upvar_ty={:?} capture={:?}", + captured_place.place, upvar_ty, capture + ); - match capture { - ty::UpvarCapture::ByValue(_) => upvar_ty, - ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref( - borrow.region, - ty::TypeAndMut { ty: upvar_ty, mutbl: borrow.kind.to_mutbl_lossy() }, - ), - } - }) + match capture { + ty::UpvarCapture::ByValue(_) => upvar_ty, + ty::UpvarCapture::ByRef(borrow) => tcx.mk_ref( + borrow.region, + ty::TypeAndMut { ty: upvar_ty, mutbl: borrow.kind.to_mutbl_lossy() }, + ), + } }) .collect() }