about summary refs log tree commit diff
path: root/src/librustc/infer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustc/infer/mod.rs')
-rw-r--r--src/librustc/infer/mod.rs61
1 files changed, 28 insertions, 33 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 4f923f0b249..7302bad0ca1 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -1463,26 +1463,17 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         !traits::type_known_to_meet_bound(self, param_env, ty, copy_def_id, span)
     }
 
+    /// Obtains the latest type of the given closure; this may be a
+    /// closure in the current function, in which case its
+    /// `ClosureKind` may not yet be known.
     pub fn closure_kind(&self,
-                        def_id: DefId)
+                        closure_def_id: DefId,
+                        closure_substs: ty::ClosureSubsts<'tcx>)
                         -> Option<ty::ClosureKind>
     {
-        if let Some(tables) = self.in_progress_tables {
-            if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
-                return tables.borrow()
-                             .closure_kinds()
-                             .get(hir_id)
-                             .cloned()
-                             .map(|(kind, _)| kind);
-            }
-        }
-
-        // During typeck, ALL closures are local. But afterwards,
-        // during trans, we see closure ids from other traits.
-        // That may require loading the closure data out of the
-        // cstore.
-        Some(self.tcx.closure_kind(def_id))
+        let closure_kind_ty = closure_substs.closure_kind_ty(closure_def_id, self.tcx);
+        let closure_kind_ty = self.shallow_resolve(&closure_kind_ty);
+        closure_kind_ty.to_opt_closure_kind()
     }
 
     /// Obtain the signature of a function or closure.
@@ -1490,11 +1481,28 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     /// work during the type-checking of the enclosing function and
     /// return the closure signature in its partially inferred state.
     pub fn fn_sig(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> {
+        // Do we have an in-progress set of tables we are inferring?
         if let Some(tables) = self.in_progress_tables {
+            // Is this a local item?
             if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
-                if let Some(&ty) = tables.borrow().closure_tys().get(hir_id) {
-                    return ty;
+                // Is it a local *closure*?
+                if self.tcx.is_closure(def_id) {
+                    let hir_id = self.tcx.hir.node_to_hir_id(id);
+                    // Is this local closure contained within the tables we are inferring?
+                    if tables.borrow().local_id_root == Some(DefId::local(hir_id.owner)) {
+                        // if so, extract signature from there.
+                        let closure_ty = tables.borrow().node_id_to_type(hir_id);
+                        let (closure_def_id, closure_substs) = match closure_ty.sty {
+                            ty::TyClosure(closure_def_id, closure_substs) =>
+                                (closure_def_id, closure_substs),
+                            _ =>
+                                bug!("closure with non-closure type: {:?}", closure_ty),
+                        };
+                        assert_eq!(def_id, closure_def_id);
+                        let closure_sig_ty = closure_substs.closure_sig_ty(def_id, self.tcx);
+                        let closure_sig_ty = self.shallow_resolve(&closure_sig_ty);
+                        return closure_sig_ty.fn_sig(self.tcx);
+                    }
                 }
             }
         }
@@ -1502,19 +1510,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.tcx.fn_sig(def_id)
     }
 
-    pub fn generator_sig(&self, def_id: DefId) -> Option<ty::PolyGenSig<'tcx>> {
-        if let Some(tables) = self.in_progress_tables {
-            if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
-                let hir_id = self.tcx.hir.node_to_hir_id(id);
-                if let Some(&ty) = tables.borrow().generator_sigs().get(hir_id) {
-                    return ty.map(|t| ty::Binder(t));
-                }
-            }
-        }
-
-        self.tcx.generator_sig(def_id)
-    }
-
     /// Normalizes associated types in `value`, potentially returning
     /// new obligations that must further be processed.
     pub fn partially_normalize_associated_types_in<T>(&self,