+ /// Finds the span of a captured variable within a closure or generator.
+ fn closure_span(
+ &self,
+ def_id: DefId,
+ target_place: &Place<'tcx>,
+ places: &Vec<Operand<'tcx>>,
+ ) -> Option<(Span, Span)> {
+ debug!(
+ "closure_span: def_id={:?} target_place={:?} places={:?}",
+ def_id, target_place, places
+ );
+ let node_id = self.infcx.tcx.hir.as_local_node_id(def_id)?;
+ let expr = &self.infcx.tcx.hir.expect_expr(node_id).node;
+ debug!("closure_span: node_id={:?} expr={:?}", node_id, expr);
+ if let hir::ExprKind::Closure(
+ .., args_span, _
+ ) = expr {
+ let var_span = self.infcx.tcx.with_freevars(
+ node_id,
+ |freevars| {
+ for (v, place) in freevars.iter().zip(places) {
+ match place {
+ Operand::Copy(place) |
+ Operand::Move(place) if target_place == place => {
+ debug!("closure_span: found captured local {:?}", place);
+ return Some(v.span);
+ },
+ _ => {}
+ }
+ }
+
+ None
+ },
+ )?;
+
+ Some((*args_span, var_span))
+ } else {
+ None
+ }
+ }
+