]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_typeck/check/generator_interior.rs
record upvar into GeneratorInteriorTypeCause
[rust.git] / src / librustc_typeck / check / generator_interior.rs
index edc8e97ec77d6202c1ec84c1282144f11f8a6d5d..aa4abcd7224268fcca52d7432d75e6d46d97fd5c 100644 (file)
@@ -16,6 +16,7 @@
 
 struct InteriorVisitor<'a, 'tcx> {
     fcx: &'a FnCtxt<'a, 'tcx>,
+    closure_def_id: DefId,
     types: FxHashMap<ty::GeneratorInteriorTypeCause<'tcx>, usize>,
     region_scope_tree: &'tcx region::ScopeTree,
     expr_count: usize,
@@ -30,6 +31,7 @@ fn record(
         scope: Option<region::Scope>,
         expr: Option<&'tcx Expr<'tcx>>,
         source_span: Span,
+        is_upvar: bool,
     ) {
         use rustc_span::DUMMY_SP;
 
@@ -96,6 +98,7 @@ fn record(
                         span: source_span,
                         ty: &ty,
                         scope_span,
+                        yield_span: Some(yield_data.span),
                         expr: expr.map(|e| e.hir_id),
                     })
                     .or_insert(entries);
@@ -116,6 +119,20 @@ fn record(
                     unresolved_type, unresolved_type_span
                 );
                 self.prev_unresolved_span = unresolved_type_span;
+            } else {
+                if is_upvar {
+                    let entries = self.types.len();
+                    let scope_span = scope.map(|s| s.span(self.fcx.tcx, self.region_scope_tree));
+                    self.types
+                        .entry(ty::GeneratorInteriorTypeCause {
+                            span: source_span,
+                            ty: &ty,
+                            scope_span,
+                            yield_span: None,
+                            expr: expr.map(|e| e.hir_id),
+                        })
+                        .or_insert(entries);
+                }
             }
         }
     }
@@ -129,8 +146,12 @@ pub fn resolve_interior<'a, 'tcx>(
     kind: hir::GeneratorKind,
 ) {
     let body = fcx.tcx.hir().body(body_id);
+
+    let closure_def_id = fcx.tcx.hir().body_owner_def_id(body_id).to_def_id();
+
     let mut visitor = InteriorVisitor {
         fcx,
+        closure_def_id,
         types: FxHashMap::default(),
         region_scope_tree: fcx.tcx.region_scope_tree(def_id),
         expr_count: 0,
@@ -222,7 +243,7 @@ fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
         if let PatKind::Binding(..) = pat.kind {
             let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
             let ty = self.fcx.tables.borrow().pat_ty(pat);
-            self.record(ty, Some(scope), None, pat.span);
+            self.record(ty, Some(scope), None, pat.span, false);
         }
     }
 
@@ -263,7 +284,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         // If there are adjustments, then record the final type --
         // this is the actual value that is being produced.
         if let Some(adjusted_ty) = self.fcx.tables.borrow().expr_ty_adjusted_opt(expr) {
-            self.record(adjusted_ty, scope, Some(expr), expr.span);
+            self.record(adjusted_ty, scope, Some(expr), expr.span, false);
         }
 
         // Also record the unadjusted type (which is the only type if
@@ -291,9 +312,17 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         // The type table might not have information for this expression
         // if it is in a malformed scope. (#66387)
         if let Some(ty) = self.fcx.tables.borrow().expr_ty_opt(expr) {
-            self.record(ty, scope, Some(expr), expr.span);
+            self.record(ty, scope, Some(expr), expr.span, false);
         } else {
             self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
         }
+
+        if let Some(upvars) = self.fcx.tcx.upvars(self.closure_def_id) {
+            for (upvar_id, upvar) in upvars.iter() {
+                let upvar_ty = self.fcx.tables.borrow().node_type(*upvar_id);
+                debug!("type of upvar: {:?}", upvar_ty);
+                self.record(upvar_ty, scope, Some(expr), upvar.span, true);
+            }
+        }
     }
 }