Skip to content

Commit a6d0c35

Browse files
authored
Rollup merge of #70089 - eddyb:closure-sig-infer, r=nikomatsakis
rustc_infer: remove InferCtxt::closure_sig as the FnSig is always shallowly known. That is, `ClosureSubsts` is always created (in `rustc_typeck::check::closure`) with a `FnSig`, as the number of inputs is known, even if they might all have inference types. The only useful thing `InferCtxt::closure_sig` was doing is resolving an inference variable used just to get the `ty::FnPtr` containing that `FnSig` into `ClosureSubsts`. The ideal way to solve this would be to add a constructor for `ClosureSubsts`, that combines the parent `Substs`, the closure kind, the signature, and capture types together, but for now I've went with resolving the inference types just after unifying them with the real types. r? @nikomatsakis
2 parents bbd1ca3 + 63811bc commit a6d0c35

File tree

15 files changed

+51
-76
lines changed

15 files changed

+51
-76
lines changed

src/librustc/ty/print/pretty.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,9 @@ pub trait PrettyPrinter<'tcx>:
681681

682682
if self.tcx().sess.verbose() {
683683
p!(write(
684-
" closure_kind_ty={:?} closure_sig_ty={:?}",
684+
" closure_kind_ty={:?} closure_sig_as_fn_ptr_ty={:?}",
685685
substs.as_closure().kind_ty(did, self.tcx()),
686-
substs.as_closure().sig_ty(did, self.tcx())
686+
substs.as_closure().sig_as_fn_ptr_ty(did, self.tcx())
687687
));
688688
}
689689

src/librustc/ty/sty.rs

+12-18
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pub struct ClosureSubsts<'tcx> {
371371
/// parent slice and not canonical substs themselves.
372372
struct SplitClosureSubsts<'tcx> {
373373
closure_kind_ty: Ty<'tcx>,
374-
closure_sig_ty: Ty<'tcx>,
374+
closure_sig_as_fn_ptr_ty: Ty<'tcx>,
375375
upvar_kinds: &'tcx [GenericArg<'tcx>],
376376
}
377377

@@ -384,7 +384,7 @@ impl<'tcx> ClosureSubsts<'tcx> {
384384
let parent_len = generics.parent_count;
385385
SplitClosureSubsts {
386386
closure_kind_ty: self.substs.type_at(parent_len),
387-
closure_sig_ty: self.substs.type_at(parent_len + 1),
387+
closure_sig_as_fn_ptr_ty: self.substs.type_at(parent_len + 1),
388388
upvar_kinds: &self.substs[parent_len + 2..],
389389
}
390390
}
@@ -412,12 +412,10 @@ impl<'tcx> ClosureSubsts<'tcx> {
412412
self.split(def_id, tcx).closure_kind_ty
413413
}
414414

415-
/// Returns the type representing the closure signature for this
416-
/// closure; may contain type variables during inference. To get
417-
/// the closure signature during inference, use
418-
/// `infcx.fn_sig(def_id)`.
419-
pub fn sig_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
420-
self.split(def_id, tcx).closure_sig_ty
415+
/// Returns the `fn` pointer type representing the closure signature for this
416+
/// closure.
417+
pub fn sig_as_fn_ptr_ty(self, def_id: DefId, tcx: TyCtxt<'_>) -> Ty<'tcx> {
418+
self.split(def_id, tcx).closure_sig_as_fn_ptr_ty
421419
}
422420

423421
/// Returns the closure kind for this closure; only usable outside
@@ -429,16 +427,12 @@ impl<'tcx> ClosureSubsts<'tcx> {
429427
self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
430428
}
431429

432-
/// Extracts the signature from the closure; only usable outside
433-
/// of an inference context, because in that context we know that
434-
/// there are no type variables.
435-
///
436-
/// If you have an inference context, use `infcx.closure_sig()`.
430+
/// Extracts the signature from the closure.
437431
pub fn sig(&self, def_id: DefId, tcx: TyCtxt<'tcx>) -> ty::PolyFnSig<'tcx> {
438-
let ty = self.sig_ty(def_id, tcx);
432+
let ty = self.sig_as_fn_ptr_ty(def_id, tcx);
439433
match ty.kind {
440434
ty::FnPtr(sig) => sig,
441-
_ => bug!("closure_sig_ty is not a fn-ptr: {:?}", ty.kind),
435+
_ => bug!("closure_sig_as_fn_ptr_ty is not a fn-ptr: {:?}", ty.kind),
442436
}
443437
}
444438
}
@@ -2200,9 +2194,9 @@ impl<'tcx> TyS<'tcx> {
22002194
// ignore errors (#54954)
22012195
ty::Binder::dummy(FnSig::fake())
22022196
}
2203-
Closure(..) => {
2204-
bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`",)
2205-
}
2197+
Closure(..) => bug!(
2198+
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
2199+
),
22062200
_ => bug!("Ty::fn_sig() called on non-fn type: {:?}", self),
22072201
}
22082202
}

src/librustc_infer/infer/mod.rs

-10
Original file line numberDiff line numberDiff line change
@@ -1506,16 +1506,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
15061506
closure_kind_ty.to_opt_closure_kind()
15071507
}
15081508

1509-
/// Obtains the signature of a closure. For closures, unlike
1510-
/// `tcx.fn_sig(def_id)`, this method will work during the
1511-
/// type-checking of the enclosing function and return the closure
1512-
/// signature in its partially inferred state.
1513-
pub fn closure_sig(&self, def_id: DefId, substs: SubstsRef<'tcx>) -> ty::PolyFnSig<'tcx> {
1514-
let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
1515-
let closure_sig_ty = self.shallow_resolve(closure_sig_ty);
1516-
closure_sig_ty.fn_sig(self.tcx)
1517-
}
1518-
15191509
/// Clears the selection, evaluation, and projection caches. This is useful when
15201510
/// repeatedly attempting to select an `Obligation` while changing only
15211511
/// its `ParamEnv`, since `FulfillmentContext` doesn't use probing.

src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1684,7 +1684,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
16841684
// case it ends up being assigned into the return place.
16851685
annotated_closure = self.annotate_fn_sig(
16861686
*def_id,
1687-
self.infcx.closure_sig(*def_id, *substs),
1687+
substs.as_closure().sig(*def_id, self.infcx.tcx),
16881688
);
16891689
debug!(
16901690
"annotate_argument_and_return_for_borrow: \

src/librustc_mir/borrow_check/type_check/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -2085,9 +2085,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
20852085

20862086
CastKind::Pointer(PointerCast::ClosureFnPointer(unsafety)) => {
20872087
let sig = match op.ty(*body, tcx).kind {
2088-
ty::Closure(def_id, substs) => {
2089-
substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx)
2090-
}
2088+
ty::Closure(def_id, substs) => substs.as_closure().sig(def_id, tcx),
20912089
_ => bug!(),
20922090
};
20932091
let ty_fn_ptr_from = tcx.coerce_closure_fn_ty(sig, *unsafety);

src/librustc_mir/borrow_check/universal_regions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
580580
match defining_ty {
581581
DefiningTy::Closure(def_id, substs) => {
582582
assert_eq!(self.mir_def_id, def_id);
583-
let closure_sig = substs.as_closure().sig_ty(def_id, tcx).fn_sig(tcx);
583+
let closure_sig = substs.as_closure().sig(def_id, tcx);
584584
let inputs_and_output = closure_sig.inputs_and_output();
585585
let closure_ty = tcx.closure_env_ty(def_id, substs).unwrap();
586586
ty::Binder::fuse(closure_ty, inputs_and_output, |closure_ty, inputs_and_output| {

src/librustc_trait_selection/opaque_types.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ where
724724
upvar_ty.visit_with(self);
725725
}
726726

727-
substs.as_closure().sig_ty(def_id, self.tcx).visit_with(self);
727+
substs.as_closure().sig_as_fn_ptr_ty(def_id, self.tcx).visit_with(self);
728728
}
729729

730730
ty::Generator(def_id, ref substs, _) => {

src/librustc_trait_selection/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
368368
let self_ty = trait_ref.self_ty();
369369
let (def_id, output_ty, callable) = match self_ty.kind {
370370
ty::Closure(def_id, substs) => {
371-
(def_id, self.closure_sig(def_id, substs).output(), "closure")
371+
(def_id, substs.as_closure().sig(def_id, self.tcx).output(), "closure")
372372
}
373373
ty::FnDef(def_id, _) => (def_id, self_ty.fn_sig(self.tcx).output(), "function"),
374374
_ => return,

src/librustc_trait_selection/traits/project.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1311,9 +1311,7 @@ fn confirm_closure_candidate<'cx, 'tcx>(
13111311
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>,
13121312
) -> Progress<'tcx> {
13131313
let tcx = selcx.tcx();
1314-
let infcx = selcx.infcx();
1315-
let closure_sig_ty = vtable.substs.as_closure().sig_ty(vtable.closure_def_id, tcx);
1316-
let closure_sig = infcx.shallow_resolve(closure_sig_ty).fn_sig(tcx);
1314+
let closure_sig = vtable.substs.as_closure().sig(vtable.closure_def_id, tcx);
13171315
let Normalized { value: closure_sig, obligations } = normalize_with_depth(
13181316
selcx,
13191317
obligation.param_env,

src/librustc_trait_selection/traits/select.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3349,9 +3349,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
33493349
"closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})",
33503350
obligation, closure_def_id, substs,
33513351
);
3352-
let closure_type = self.infcx.closure_sig(closure_def_id, substs);
3352+
let closure_sig = substs.as_closure().sig(closure_def_id, self.tcx());
33533353

3354-
debug!("closure_trait_ref_unnormalized: closure_type = {:?}", closure_type);
3354+
debug!("closure_trait_ref_unnormalized: closure_sig = {:?}", closure_sig);
33553355

33563356
// (1) Feels icky to skip the binder here, but OTOH we know
33573357
// that the self-type is an unboxed closure type and hence is
@@ -3362,7 +3362,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
33623362
self.tcx(),
33633363
obligation.predicate.def_id(),
33643364
obligation.predicate.skip_binder().self_ty(), // (1)
3365-
closure_type,
3365+
closure_sig,
33663366
util::TupleArgumentsFlag::No,
33673367
)
33683368
.map_bound(|(trait_ref, _)| trait_ref)

src/librustc_typeck/check/callee.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
105105
// haven't yet decided on whether the closure is fn vs
106106
// fnmut vs fnonce. If so, we have to defer further processing.
107107
if self.closure_kind(def_id, substs).is_none() {
108-
let closure_ty = self.closure_sig(def_id, substs);
109-
let fn_sig = self
108+
let closure_sig = substs.as_closure().sig(def_id, self.tcx);
109+
let closure_sig = self
110110
.replace_bound_vars_with_fresh_vars(
111111
call_expr.span,
112112
infer::FnCall,
113-
&closure_ty,
113+
&closure_sig,
114114
)
115115
.0;
116116
let adjustments = autoderef.adjust_steps(self, Needs::None);
@@ -121,12 +121,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
121121
callee_expr,
122122
adjusted_ty,
123123
adjustments,
124-
fn_sig,
124+
fn_sig: closure_sig,
125125
closure_def_id: def_id,
126126
closure_substs: substs,
127127
},
128128
);
129-
return Some(CallStep::DeferredClosure(fn_sig));
129+
return Some(CallStep::DeferredClosure(closure_sig));
130130
}
131131
}
132132

src/librustc_typeck/check/closure.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
116116
interior,
117117
generator_substs.witness(expr_def_id, self.tcx),
118118
);
119-
return self.tcx.mk_generator(expr_def_id, substs, movability);
120-
}
121119

122-
let closure_type = self.tcx.mk_closure(expr_def_id, substs);
120+
// HACK(eddyb) this forces the types equated above into `substs` but
121+
// it should rely on `GeneratorSubsts` providing a constructor, instead.
122+
let substs = self.resolve_vars_if_possible(&substs);
123123

124-
debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type);
124+
return self.tcx.mk_generator(expr_def_id, substs, movability);
125+
}
125126

126127
// Tuple up the arguments and insert the resulting function type into
127128
// the `closures` table.
@@ -144,7 +145,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
144145
self.demand_eqtype(
145146
expr.span,
146147
sig_fn_ptr_ty,
147-
substs.as_closure().sig_ty(expr_def_id, self.tcx),
148+
substs.as_closure().sig_as_fn_ptr_ty(expr_def_id, self.tcx),
148149
);
149150

150151
if let Some(kind) = opt_kind {
@@ -155,6 +156,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
155156
);
156157
}
157158

159+
// HACK(eddyb) this forces the types equated above into `substs` but
160+
// it should rely on `ClosureSubsts` providing a constructor, instead.
161+
let substs = self.resolve_vars_if_possible(&substs);
162+
163+
let closure_type = self.tcx.mk_closure(expr_def_id, substs);
164+
165+
debug!("check_closure: expr.hir_id={:?} closure_type={:?}", expr.hir_id, closure_type);
166+
158167
closure_type
159168
}
160169

src/librustc_typeck/check/coercion.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -750,9 +750,9 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
750750
// `fn(arg0,arg1,...) -> _`
751751
// or
752752
// `unsafe fn(arg0,arg1,...) -> _`
753-
let sig = self.closure_sig(def_id_a, substs_a);
753+
let closure_sig = substs_a.as_closure().sig(def_id_a, self.tcx);
754754
let unsafety = fn_ty.unsafety();
755-
let pointer_ty = self.tcx.coerce_closure_fn_ty(sig, unsafety);
755+
let pointer_ty = self.tcx.coerce_closure_fn_ty(closure_sig, unsafety);
756756
debug!("coerce_closure_to_fn(a={:?}, b={:?}, pty={:?})", a, b, pointer_ty);
757757
self.unify_and(
758758
pointer_ty,

src/librustc_typeck/check/mod.rs

+1-12
Original file line numberDiff line numberDiff line change
@@ -4837,18 +4837,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
48374837
let hir = self.tcx.hir();
48384838
let (def_id, sig) = match found.kind {
48394839
ty::FnDef(def_id, _) => (def_id, found.fn_sig(self.tcx)),
4840-
ty::Closure(def_id, substs) => {
4841-
// We don't use `closure_sig` to account for malformed closures like
4842-
// `|_: [_; continue]| {}` and instead we don't suggest anything.
4843-
let closure_sig_ty = substs.as_closure().sig_ty(def_id, self.tcx);
4844-
(
4845-
def_id,
4846-
match closure_sig_ty.kind {
4847-
ty::FnPtr(sig) => sig,
4848-
_ => return false,
4849-
},
4850-
)
4851-
}
4840+
ty::Closure(def_id, substs) => (def_id, substs.as_closure().sig(def_id, self.tcx)),
48524841
_ => return false,
48534842
};
48544843

src/librustc_typeck/collect.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -1527,16 +1527,13 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
15271527
// argument. In any case they are embedded within the
15281528
// closure type as part of the `ClosureSubsts`.
15291529
//
1530-
// To get
1531-
// the signature of a closure, you should use the
1532-
// `closure_sig` method on the `ClosureSubsts`:
1530+
// To get the signature of a closure, you should use the
1531+
// `sig` method on the `ClosureSubsts`:
15331532
//
1534-
// closure_substs.sig(def_id, tcx)
1535-
//
1536-
// or, inside of an inference context, you can use
1537-
//
1538-
// infcx.closure_sig(def_id, closure_substs)
1539-
bug!("to get the signature of a closure, use `closure_sig()` not `fn_sig()`");
1533+
// substs.as_closure().sig(def_id, tcx)
1534+
bug!(
1535+
"to get the signature of a closure, use `substs.as_closure().sig()` not `fn_sig()`",
1536+
);
15401537
}
15411538

15421539
x => {

0 commit comments

Comments
 (0)