diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index cb01d821c1871..8fbb9f0891a00 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -681,9 +681,9 @@ pub trait PrettyPrinter<'tcx>: if self.tcx().sess.verbose() { p!(write( - " closure_kind_ty={:?} closure_sig_ty={:?}", + " closure_kind_ty={:?} closure_sig_as_fn_ptr_ty={:?}", substs.as_closure().kind_ty(did, self.tcx()), - substs.as_closure().sig_ty(did, self.tcx()) + substs.as_closure().sig_as_fn_ptr_ty(did, self.tcx()) )); } diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index e265a2f8257fb..a4a8c2374435f 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -371,7 +371,7 @@ pub struct ClosureSubsts<'tcx> { /// parent slice and not canonical substs themselves. struct SplitClosureSubsts<'tcx> { closure_kind_ty: Ty<'tcx>, - closure_sig_ty: Ty<'tcx>, + closure_sig_as_fn_ptr_ty: Ty<'tcx>, upvar_kinds: &'tcx [GenericArg<'tcx>], } @@ -384,7 +384,7 @@ impl<'tcx> ClosureSubsts<'tcx> { let parent_len = generics.parent_count; SplitClosureSubsts { closure_kind_ty: self.substs.type_at(parent_len), - closure_sig_ty: self.substs.type_at(parent_len + 1), + closure_sig_as_fn_ptr_ty: self.substs.type_at(parent_len + 1), upvar_kinds: &self.substs[parent_len + 2..], } } @@ -412,12 +412,10 @@ impl<'tcx> ClosureSubsts<'tcx> { self.split(def_id, tcx).closure_kind_ty } - /// Returns the type representing the closure signature for this - /// closure; may contain type variables during inference. To get - /// the closure signature during inference, use - /// `infcx.fn_sig(def_id)`. - pub fn sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { - self.split(def_id, tcx).closure_sig_ty + /// Returns the `fn` pointer type representing the closure signature for this + /// closure. + pub fn sig_as_fn_ptr_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> { + self.split(def_id, tcx).closure_sig_as_fn_ptr_ty } /// Returns the closure kind for this closure; only usable outside @@ -429,16 +427,12 @@ impl<'tcx> ClosureSubsts<'tcx> { self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap() } - /// 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()`. + /// Extracts the signature from the closure. pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> { - let ty = self.sig_ty(def_id, tcx); + let ty = self.sig_as_fn_ptr_ty(def_id, tcx); match ty.kind { ty::FnPtr(sig) => sig, - _ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.kind), + _ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind), } } } @@ -2200,9 +2194,9 @@ impl<'tcx> TyS<'tcx> { // ignore errors (#54954) ty::Binder::dummy(FnSig::fake()) } - Closure(..) => { - bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`",) - } + Closure(..) => bug!( + "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`", + ), _ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self), } } diff --git a/src/librustc_infer/infer/mod.rs b/src/librustc_infer/infer/mod.rs index 9ae131c568d0d..0d8dcf18bbbda 100644 --- a/src/librustc_infer/infer/mod.rs +++ b/src/librustc_infer/infer/mod.rs @@ -1486,16 +1486,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { closure_kind_ty.to_opt_closure_kind() } - /// Obtains 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: SubstsRef<'tcx>) -> ty::PolyFnSig<'tcx> { - let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx); - let closure_sig_ty = self.shallow_resolve(closure_sig_ty); - closure_sig_ty.fn_sig(self.tcx) - } - /// Clears the selection, evaluation, and projection caches. This is useful when /// repeatedly attempting to select an `Obligation` while changing only /// its `ParamEnv`, since `FulfillmentContext` doesn't use probing. diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index e895eec5d52af..c545b6df70c11 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -1684,7 +1684,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // case it ends up being assigned into the return place. annotated_closure = self.annotate_fn_sig( *def_id, - self.infcx.closure_sig(*def_id, *substs), + substs.as_closure().sig(*def_id, self.infcx.tcx), ); debug!( "annotate_argument_and_return_for_borrow: \ diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index d98abc57bfd49..bac69da12d76e 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -2083,9 +2083,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => { let sig = match op.ty(*body, tcx).kind { - ty::Closure(def_id, substs) => { - substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx) - } + ty::Closure(def_id, substs) => substs.as_closure().sig(def_id, tcx), _ => bug!(), }; let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety); diff --git a/src/librustc_mir/borrow_check/universal_regions.rs b/src/librustc_mir/borrow_check/universal_regions.rs index 67b00e9ffdd5f..dcf14bd20db60 100644 --- a/src/librustc_mir/borrow_check/universal_regions.rs +++ b/src/librustc_mir/borrow_check/universal_regions.rs @@ -580,7 +580,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { match defining_ty { DefiningTy::Closure(def_id, substs) => { assert_eq!(self.mir_def_id, def_id); - let closure_sig = substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx); + let closure_sig = substs.as_closure().sig(def_id, tcx); let inputs_and_output = closure_sig.inputs_and_output(); let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap(); ty::Binder::fuse(closure_ty, inputs_and_output, |closure_ty, inputs_and_output| { diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs index 6cf1302783c0b..c068fef12c5dc 100644 --- a/src/librustc_trait_selection/opaque_types.rs +++ b/src/librustc_trait_selection/opaque_types.rs @@ -724,7 +724,7 @@ where upvar_ty.visit_with(self); } - substs.as_closure().sig_ty(def_id, self.tcx).visit_with(self); + substs.as_closure().sig_as_fn_ptr_ty(def_id, self.tcx).visit_with(self); } ty::Generator(def_id, ref substs, _) => { diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs index 6fe6d7aab2832..8ba206031860d 100644 --- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs +++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs @@ -368,7 +368,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { let self_ty = trait_ref.self_ty(); let (def_id, output_ty, callable) = match self_ty.kind { ty::Closure(def_id, substs) => { - (def_id, self.closure_sig(def_id, substs).output(), "closure") + (def_id, substs.as_closure().sig(def_id, self.tcx).output(), "closure") } ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"), _ => return, diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 1ad915742127e..6b14f6959bfb9 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -1311,9 +1311,7 @@ fn confirm_closure_candidate<'cx, 'tcx>( vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>, ) -> Progress<'tcx> { let tcx = selcx.tcx(); - let infcx = selcx.infcx(); - let closure_sig_ty = vtable.substs.as_closure().sig_ty(vtable.closure_def_id, tcx); - let closure_sig = infcx.shallow_resolve(closure_sig_ty).fn_sig(tcx); + let closure_sig = vtable.substs.as_closure().sig(vtable.closure_def_id, tcx); let Normalized { value: closure_sig, obligations } = normalize_with_depth( selcx, obligation.param_env, diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs index ab3214d8d2d23..660d4d14bc728 100644 --- a/src/librustc_trait_selection/traits/select.rs +++ b/src/librustc_trait_selection/traits/select.rs @@ -3349,9 +3349,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { "closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})", obligation, closure_def_id, substs, ); - let closure_type = self.infcx.closure_sig(closure_def_id, substs); + let closure_sig = substs.as_closure().sig(closure_def_id, self.tcx()); - debug!("closure_trait_ref_unnormalized: closure_type = {:?}", closure_type); + debug!("closure_trait_ref_unnormalized: closure_sig = {:?}", closure_sig); // (1) Feels icky to skip the binder here, but OTOH we know // that the self-type is an unboxed closure type and hence is @@ -3362,7 +3362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.tcx(), obligation.predicate.def_id(), obligation.predicate.skip_binder().self_ty(), // (1) - closure_type, + closure_sig, util::TupleArgumentsFlag::No, ) .map_bound(|(trait_ref, _)| trait_ref) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 3f8019e64b2db..056fe912d9e34 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -105,12 +105,12 @@ impl<'a, 'tcx> FnCtxt<'a, '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.closure_sig(def_id, substs); - let fn_sig = self + let closure_sig = substs.as_closure().sig(def_id, self.tcx); + let closure_sig = self .replace_bound_vars_with_fresh_vars( call_expr.span, infer::FnCall, - &closure_ty, + &closure_sig, ) .0; let adjustments = autoderef.adjust_steps(self, Needs::None); @@ -121,12 +121,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_expr, adjusted_ty, adjustments, - fn_sig, + fn_sig: closure_sig, closure_def_id: def_id, closure_substs: substs, }, ); - return Some(CallStep::DeferredClosure(fn_sig)); + return Some(CallStep::DeferredClosure(closure_sig)); } } diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 49b7a99731104..d8f5a83c50b2d 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -116,12 +116,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { interior, generator_substs.witness(expr_def_id, self.tcx), ); - return self.tcx.mk_generator(expr_def_id, substs, movability); - } - let closure_type = self.tcx.mk_closure(expr_def_id, substs); + // HACK(eddyb) this forces the types equated above into `substs` but + // it should rely on `GeneratorSubsts` providing a constructor, instead. + let substs = self.resolve_vars_if_possible(&substs); - debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type); + return self.tcx.mk_generator(expr_def_id, substs, movability); + } // Tuple up the arguments and insert the resulting function type into // the `closures` table. @@ -144,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.demand_eqtype( expr.span, sig_fn_ptr_ty, - substs.as_closure().sig_ty(expr_def_id, self.tcx), + substs.as_closure().sig_as_fn_ptr_ty(expr_def_id, self.tcx), ); if let Some(kind) = opt_kind { @@ -155,6 +156,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } + // HACK(eddyb) this forces the types equated above into `substs` but + // it should rely on `ClosureSubsts` providing a constructor, instead. + let substs = self.resolve_vars_if_possible(&substs); + + let closure_type = self.tcx.mk_closure(expr_def_id, substs); + + debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type); + closure_type } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d74623a063f8f..689425bc19f20 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -749,9 +749,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { // `fn(arg0,arg1,...) -> _` // or // `unsafe fn(arg0,arg1,...) -> _` - let sig = self.closure_sig(def_id_a, substs_a); + let closure_sig = substs_a.as_closure().sig(def_id_a, self.tcx); let unsafety = fn_ty.unsafety(); - let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety); + let pointer_ty = self.tcx.coerce_closure_fn_ty(closure_sig, unsafety); debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty); self.unify_and( pointer_ty, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1766b688468f1..bbc7593fd7acc 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4839,18 +4839,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let hir = self.tcx.hir(); let (def_id, sig) = match found.kind { ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)), - ty::Closure(def_id, substs) => { - // We don't use `closure_sig` to account for malformed closures like - // `|_: [_; continue]| {}` and instead we don't suggest anything. - let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx); - ( - def_id, - match closure_sig_ty.kind { - ty::FnPtr(sig) => sig, - _ => return false, - }, - ) - } + ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig(def_id, self.tcx)), _ => return false, }; diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 8e60bd2a4b3e8..055390780b40f 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1527,16 +1527,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> { // argument. In any case they are embedded within the // closure type as part of the `ClosureSubsts`. // - // To get - // the signature of a closure, you should use the - // `closure_sig` method on the `ClosureSubsts`: + // To get the signature of a closure, you should use the + // `sig` method on the `ClosureSubsts`: // - // closure_substs.sig(def_id, tcx) - // - // or, inside of an inference context, you can use - // - // infcx.closure_sig(def_id, closure_substs) - bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`"); + // substs.as_closure().sig(def_id, tcx) + bug!( + "to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`", + ); } x => {