@@ -56,11 +56,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
56
56
expected_sig) ;
57
57
58
58
let expr_def_id = self . tcx . hir . local_def_id ( expr. id ) ;
59
- let sig = AstConv :: ty_of_closure ( self ,
60
- hir:: Unsafety :: Normal ,
61
- decl,
62
- Abi :: RustCall ,
63
- expected_sig) ;
59
+ let sig = self . ty_of_closure ( decl, expected_sig) ;
64
60
65
61
debug ! ( "check_closure: ty_of_closure returns {:?}" , sig) ;
66
62
@@ -274,4 +270,72 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
274
270
_ => None ,
275
271
}
276
272
}
273
+
274
+ /// Invoked to compute the signature of a closure expression. This
275
+ /// combines any user-provided type annotations (e.g., `|x: u32|
276
+ /// -> u32 { .. }`) with the expected signature.
277
+ ///
278
+ /// The arguments here are a bit odd-ball:
279
+ ///
280
+ /// - `decl`: the HIR declaration of the closure
281
+ /// - `expected_sig`: the expected signature (if any). Note that
282
+ /// this is missing a binder: that is, there may be late-bound
283
+ /// regions with depth 1, which are bound then by the closure.
284
+ fn ty_of_closure ( & self ,
285
+ decl : & hir:: FnDecl ,
286
+ expected_sig : Option < ty:: FnSig < ' tcx > > )
287
+ -> ty:: PolyFnSig < ' tcx >
288
+ {
289
+ let astconv: & AstConv = self ;
290
+
291
+ debug ! ( "ty_of_closure(expected_sig={:?})" ,
292
+ expected_sig) ;
293
+
294
+ let input_tys = decl. inputs . iter ( ) . enumerate ( ) . map ( |( i, a) | {
295
+ let expected_arg_ty = expected_sig. as_ref ( ) . and_then ( |e| {
296
+ // no guarantee that the correct number of expected args
297
+ // were supplied
298
+ if i < e. inputs ( ) . len ( ) {
299
+ Some ( e. inputs ( ) [ i] )
300
+ } else {
301
+ None
302
+ }
303
+ } ) ;
304
+
305
+ let input_ty = astconv. ty_of_arg ( a, expected_arg_ty) ;
306
+ debug ! ( "ty_of_closure: i={} input_ty={:?} expected_arg_ty={:?}" ,
307
+ i, input_ty, expected_arg_ty) ;
308
+
309
+ input_ty
310
+ } ) ;
311
+
312
+ let expected_ret_ty = expected_sig. as_ref ( ) . map ( |e| e. output ( ) ) ;
313
+
314
+ let output_ty = match decl. output {
315
+ hir:: Return ( ref output) => {
316
+ if let ( & hir:: TyInfer , Some ( expected_ret_ty) ) = ( & output. node , expected_ret_ty) {
317
+ astconv. record_ty ( output. hir_id , expected_ret_ty, output. span ) ;
318
+ expected_ret_ty
319
+ } else {
320
+ astconv. ast_ty_to_ty ( & output)
321
+ }
322
+ }
323
+ hir:: DefaultReturn ( span) => {
324
+ if let Some ( expected_ret_ty) = expected_ret_ty {
325
+ expected_ret_ty
326
+ } else {
327
+ astconv. ty_infer ( span)
328
+ }
329
+ }
330
+ } ;
331
+
332
+ debug ! ( "ty_of_closure: output_ty={:?}" , output_ty) ;
333
+
334
+ ty:: Binder ( self . tcx . mk_fn_sig (
335
+ input_tys,
336
+ output_ty,
337
+ decl. variadic ,
338
+ hir:: Unsafety :: Normal ,
339
+ Abi :: RustCall ) )
340
+ }
277
341
}
0 commit comments