@@ -173,7 +173,7 @@ pub enum TypeVariants<'tcx> {
173
173
174
174
/// A closure can be modeled as a struct that looks like:
175
175
///
176
- /// struct Closure<'l0...'li, T0...Tj, CK, U0...Uk> {
176
+ /// struct Closure<'l0...'li, T0...Tj, CK, CS, U0...Uk> {
177
177
/// upvar0: U0,
178
178
/// ...
179
179
/// upvark: Uk
@@ -186,6 +186,10 @@ pub enum TypeVariants<'tcx> {
186
186
/// - CK represents the *closure kind* (Fn vs FnMut vs FnOnce). This
187
187
/// is rather hackily encoded via a scalar type. See
188
188
/// `TyS::to_opt_closure_kind` for details.
189
+ /// - CS represents the *closure signature*, representing as a `fn()`
190
+ /// type. For example, `fn(u32, u32) -> u32` would mean that the closure
191
+ /// implements `CK<(u32, u32), Output = u32>`, where `CK` is the trait
192
+ /// specified above.
189
193
/// - U0...Uk are type parameters representing the types of its upvars
190
194
/// (borrowed, if appropriate; that is, if Ui represents a by-ref upvar,
191
195
/// and the up-var has the type `Foo`, then `Ui = &Foo`).
@@ -265,6 +269,7 @@ pub struct ClosureSubsts<'tcx> {
265
269
/// parent slice and not canonical substs themselves.
266
270
struct SplitClosureSubsts < ' tcx > {
267
271
closure_kind_ty : Ty < ' tcx > ,
272
+ closure_sig_ty : Ty < ' tcx > ,
268
273
upvar_kinds : & ' tcx [ Kind < ' tcx > ] ,
269
274
}
270
275
@@ -276,8 +281,9 @@ impl<'tcx> ClosureSubsts<'tcx> {
276
281
let generics = tcx. generics_of ( def_id) ;
277
282
let parent_len = generics. parent_count ( ) ;
278
283
SplitClosureSubsts {
279
- closure_kind_ty : self . substs [ parent_len] . as_type ( ) . expect ( "closure-kind should be type" ) ,
280
- upvar_kinds : & self . substs [ parent_len + 1 ..] ,
284
+ closure_kind_ty : self . substs [ parent_len] . as_type ( ) . expect ( "CK should be a type" ) ,
285
+ closure_sig_ty : self . substs [ parent_len + 1 ] . as_type ( ) . expect ( "CS should be a type" ) ,
286
+ upvar_kinds : & self . substs [ parent_len + 2 ..] ,
281
287
}
282
288
}
283
289
@@ -294,6 +300,20 @@ impl<'tcx> ClosureSubsts<'tcx> {
294
300
pub fn closure_kind_ty ( self , def_id : DefId , tcx : TyCtxt < ' _ , ' _ , ' _ > ) -> Ty < ' tcx > {
295
301
self . split ( def_id, tcx) . closure_kind_ty
296
302
}
303
+
304
+ /// Returns the type representing the closure signature for this
305
+ /// closure; may contain type variables during inference.
306
+ pub fn closure_sig_ty ( self , def_id : DefId , tcx : TyCtxt < ' _ , ' _ , ' _ > ) -> Ty < ' tcx > {
307
+ self . split ( def_id, tcx) . closure_sig_ty
308
+ }
309
+
310
+ /// Extracts the signature from the closure.
311
+ pub fn closure_sig ( self , def_id : DefId , tcx : TyCtxt < ' _ , ' _ , ' _ > ) -> ty:: PolyFnSig < ' tcx > {
312
+ match & self . split ( def_id, tcx) . closure_sig_ty . sty {
313
+ ty:: TyFnPtr ( sig) => * sig,
314
+ t => bug ! ( "closure_sig_ty is not a fn-ptr: {:?}" , t) ,
315
+ }
316
+ }
297
317
}
298
318
299
319
impl < ' tcx > ClosureSubsts < ' tcx > {
0 commit comments