let fn_def_id = tcx_hir.local_def_id(fn_id);
// Gather the upvars of a closure, if any.
- let upvar_decls: Vec<_> = match hir_tables.upvar_list.get(&fn_def_id) {
- Some(upvars) => upvars
- .iter()
- .map(|upvar_id| {
- let var_hir_id = upvar_id.var_path.hir_id;
- let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
- let capture = hir_tables.upvar_capture(*upvar_id);
- let by_ref = match capture {
- ty::UpvarCapture::ByValue => false,
- ty::UpvarCapture::ByRef(..) => true,
- };
- let mut decl = UpvarDecl {
- debug_name: keywords::Invalid.name(),
- var_hir_id: ClearCrossCrate::Set(var_hir_id),
- by_ref,
- mutability: Mutability::Not,
- };
- if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
- if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
- decl.debug_name = ident.name;
- if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
- if bm == ty::BindByValue(hir::MutMutable) {
- decl.mutability = Mutability::Mut;
- } else {
- decl.mutability = Mutability::Not;
- }
+ // In analyze_closure() in upvar.rs we gathered a list of upvars used by a
+ // closure and we stored in a map called upvar_list in TypeckTables indexed
+ // with the closure's DefId. Here, we run through that vec of UpvarIds for
+ // the given closure and use the necessary information to create UpvarDecl.
+ let upvar_decls: Vec<_> = hir_tables
+ .upvar_list
+ .get(&fn_def_id)
+ .into_iter()
+ .flatten()
+ .map(|upvar_id| {
+ let var_hir_id = upvar_id.var_path.hir_id;
+ let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
+ let capture = hir_tables.upvar_capture(*upvar_id);
+ let by_ref = match capture {
+ ty::UpvarCapture::ByValue => false,
+ ty::UpvarCapture::ByRef(..) => true,
+ };
+ let mut decl = UpvarDecl {
+ debug_name: keywords::Invalid.name(),
+ var_hir_id: ClearCrossCrate::Set(var_hir_id),
+ by_ref,
+ mutability: Mutability::Not,
+ };
+ if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
+ if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
+ decl.debug_name = ident.name;
+ if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
+ if bm == ty::BindByValue(hir::MutMutable) {
+ decl.mutability = Mutability::Mut;
} else {
- tcx.sess.delay_span_bug(pat.span, "missing binding mode");
+ decl.mutability = Mutability::Not;
}
+ } else {
+ tcx.sess.delay_span_bug(pat.span, "missing binding mode");
}
}
- decl
- })
- .collect(),
- _ => vec![],
- };
+ }
+ decl
+ })
+ .collect();
let mut builder = Builder::new(hir,
span,
///////////////////////////////////////////////////////////////////////////
// Entry point
-/// During type inference, partially inferred types are
-/// represented using Type variables (ty::Infer). These don't appear in
-/// the final TypeckTables since all of the types should have been
-/// inferred once typeck_tables_of is done.
-/// When type inference is running however, having to update the typeck
-/// tables every time a new type is inferred would be unreasonably slow,
-/// so instead all of the replacement happens at the end in
-/// resolve_type_vars_in_body, which creates a new TypeTables which
-/// doesn't contain any inference types.
+// During type inference, partially inferred types are
+// represented using Type variables (ty::Infer). These don't appear in
+// the final TypeckTables since all of the types should have been
+// inferred once typeck_tables_of is done.
+// When type inference is running however, having to update the typeck
+// tables every time a new type is inferred would be unreasonably slow,
+// so instead all of the replacement happens at the end in
+// resolve_type_vars_in_body, which creates a new TypeTables which
+// doesn't contain any inference types.
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::TypeckTables<'gcx> {
let item_id = self.tcx.hir().body_owner(body.id());