From d5ef3e262f23d419750d7d96dce69ff17baf0e5b Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 1 Dec 2017 08:51:01 -0500 Subject: [PATCH] replace `InferCtxt::fn_sig` with `closure_sig` --- src/librustc/infer/mod.rs | 44 +++++-------------- src/librustc/traits/project.rs | 17 +++---- src/librustc/traits/select.rs | 3 +- src/librustc/ty/sty.rs | 4 ++ .../borrow_check/nll/universal_regions.rs | 10 +++++ src/librustc_typeck/check/callee.rs | 3 +- src/librustc_typeck/check/coercion.rs | 3 +- 7 files changed, 38 insertions(+), 46 deletions(-) diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 0d4d294ad36..f5595d07340 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1480,38 +1480,18 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { closure_kind_ty.to_opt_closure_kind() } - /// Obtain the signature of a function or closure. - /// For closures, unlike `tcx.fn_sig(def_id)`, this method will - /// 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) { - // 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); - } - } - } - } - - self.tcx.fn_sig(def_id) + /// Obtain the signature of a closure. For closures, unlike + /// `tcx.fn_sig(def_id)`, this method will work during the + /// type-checking of the enclosing function and return the closure + /// signature in its partially inferred state. + pub fn closure_sig( + &self, + def_id: DefId, + substs: ty::ClosureSubsts<'tcx> + ) -> ty::PolyFnSig<'tcx> { + let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx); + let closure_sig_ty = self.shallow_resolve(&closure_sig_ty); + closure_sig_ty.fn_sig(self.tcx) } /// Normalizes associated types in `value`, potentially returning diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 429771cca98..3342d13dd6e 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -1339,26 +1339,27 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>( vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>) -> Progress<'tcx> { - let closure_typer = selcx.closure_typer(); - let closure_type = closure_typer.fn_sig(vtable.closure_def_id) - .subst(selcx.tcx(), vtable.substs.substs); + let tcx = selcx.tcx(); + let infcx = selcx.infcx(); + let closure_sig_ty = vtable.substs.closure_sig_ty(vtable.closure_def_id, tcx); + let closure_sig = infcx.shallow_resolve(&closure_sig_ty).fn_sig(tcx); let Normalized { - value: closure_type, + value: closure_sig, obligations } = normalize_with_depth(selcx, obligation.param_env, obligation.cause.clone(), obligation.recursion_depth+1, - &closure_type); + &closure_sig); - debug!("confirm_closure_candidate: obligation={:?},closure_type={:?},obligations={:?}", + debug!("confirm_closure_candidate: obligation={:?},closure_sig={:?},obligations={:?}", obligation, - closure_type, + closure_sig, obligations); confirm_callable_candidate(selcx, obligation, - closure_type, + closure_sig, util::TupleArgumentsFlag::No) .with_addl_obligations(vtable.nested) .with_addl_obligations(obligations) diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 0c4071b8b5d..e70de0e566e 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -3183,8 +3183,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { substs: ty::ClosureSubsts<'tcx>) -> ty::PolyTraitRef<'tcx> { - let closure_type = self.infcx.fn_sig(closure_def_id) - .subst(self.tcx(), substs.substs); + let closure_type = self.infcx.closure_sig(closure_def_id, substs); let ty::Binder((trait_ref, _)) = self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(), obligation.predicate.0.self_ty(), // (1) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 24cf14419e4..1755382516a 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -356,6 +356,8 @@ impl<'tcx> ClosureSubsts<'tcx> { /// Returns the closure kind for this closure; only usable outside /// of an inference context, because in that context we know that /// there are no type variables. + /// + /// If you have an inference context, use `infcx.closure_kind()`. pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::ClosureKind { self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap() } @@ -363,6 +365,8 @@ impl<'tcx> ClosureSubsts<'tcx> { /// Extracts the signature from the closure; only usable outside /// of an inference context, because in that context we know that /// there are no type variables. + /// + /// If you have an inference context, use `infcx.closure_sig()`. pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> { match self.closure_sig_ty(def_id, tcx).sty { ty::TyFnPtr(sig) => sig, diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index 35c50f94190..b614e280c55 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -381,7 +381,10 @@ const FR: NLLRegionVariableOrigin = NLLRegionVariableOrigin::FreeRegion; impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { fn build(mut self) -> UniversalRegions<'tcx> { + debug!("build(mir_def_id={:?})", self.mir_def_id); + let param_env = self.param_env; + debug!("build: param_env={:?}", param_env); assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars()); @@ -393,8 +396,10 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { let first_extern_index = self.infcx.num_region_vars(); let defining_ty = self.defining_ty(); + debug!("build: defining_ty={:?}", defining_ty); let indices = self.compute_indices(fr_static, defining_ty); + debug!("build: indices={:?}", indices); let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty); @@ -410,12 +415,14 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { // Add the implied bounds from inputs and outputs. for ty in inputs_and_output { + debug!("build: input_or_output={:?}", ty); self.add_implied_bounds(&indices, ty); } // Finally, outlives is reflexive, and static outlives every // other free region. for fr in (FIRST_GLOBAL_INDEX..num_universals).map(RegionVid::new) { + debug!("build: relating free region {:?} to itself and to 'static", fr); self.relations.relate_universal_regions(fr, fr); self.relations.relate_universal_regions(fr_static, fr); } @@ -562,6 +569,7 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { /// /// Assumes that `universal_regions` indices map is fully constructed. fn add_implied_bounds(&mut self, indices: &UniversalRegionIndices<'tcx>, ty: Ty<'tcx>) { + debug!("add_implied_bounds(ty={:?})", ty); let span = self.infcx.tcx.def_span(self.mir_def_id); let bounds = self.infcx .implied_outlives_bounds(self.param_env, self.mir_node_id, ty, span); @@ -576,6 +584,8 @@ impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> { I: IntoIterator>, { for outlives_bound in outlives_bounds { + debug!("add_outlives_bounds(bound={:?})", outlives_bound); + match outlives_bound { OutlivesBound::RegionSubRegion(r1, r2) => { // The bound says that `r1 <= r2`; we store `r2: r1`. diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 8f409b68752..df1694a6010 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -16,7 +16,6 @@ use hir::def::Def; use hir::def_id::{DefId, LOCAL_CRATE}; use rustc::{infer, traits}; use rustc::ty::{self, TyCtxt, TypeFoldable, LvaluePreference, Ty}; -use rustc::ty::subst::Subst; use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow}; use syntax::abi; use syntax::symbol::Symbol; @@ -109,7 +108,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // haven't yet decided on whether the closure is fn vs // fnmut vs fnonce. If so, we have to defer further processing. if self.closure_kind(def_id, substs).is_none() { - let closure_ty = self.fn_sig(def_id).subst(self.tcx, substs.substs); + let closure_ty = self.closure_sig(def_id, substs); let fn_sig = self.replace_late_bound_regions_with_fresh_var(call_expr.span, infer::FnCall, &closure_ty) diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 3e725d7ef41..dc5d3141d4c 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -74,7 +74,6 @@ use rustc::ty::{self, LvaluePreference, TypeAndMut, use rustc::ty::fold::TypeFoldable; use rustc::ty::error::TypeError; use rustc::ty::relate::RelateResult; -use rustc::ty::subst::Subst; use errors::DiagnosticBuilder; use syntax::abi; use syntax::feature_gate; @@ -670,7 +669,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // `extern "rust-call" fn((arg0,arg1,...)) -> _` // to // `fn(arg0,arg1,...) -> _` - let sig = self.fn_sig(def_id_a).subst(self.tcx, substs_a.substs); + let sig = self.closure_sig(def_id_a, substs_a); let converted_sig = sig.map_bound(|s| { let params_iter = match s.inputs()[0].sty { ty::TyTuple(params, _) => {