diff options
Diffstat (limited to 'src/librustc/infer/mod.rs')
| -rw-r--r-- | src/librustc/infer/mod.rs | 61 |
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, |
