1313use super :: { check_fn, Expectation , FnCtxt } ;
1414
1515use astconv:: AstConv ;
16+ use rustc:: hir:: def_id:: DefId ;
1617use rustc:: ty:: { self , ToPolyTraitRef , Ty } ;
18+ use rustc:: ty:: subst:: Substs ;
1719use rustc:: util:: common:: MemoizationMap ;
1820use std:: cmp;
1921use syntax:: abi:: Abi ;
@@ -43,20 +45,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
4345 self . check_closure ( expr, expected_kind, decl, body, expected_sig)
4446 }
4547
48+ fn declare_closure ( & self , def_id : DefId ) {
49+ let tcx = self . tcx . global_tcx ( ) ;
50+
51+ tcx. generics . memoize ( def_id, || {
52+ let node_id = tcx. map . as_local_node_id ( def_id) . unwrap ( ) ;
53+ let base_def_id = self . tcx . closure_base_def_id ( def_id) ;
54+ let base_generics = tcx. item_generics ( base_def_id) ;
55+
56+ // provide junk type parameter defs - the only place that
57+ // cares about anything but the length is instantiation,
58+ // and we don't do that for closures.
59+ let upvar_decls : Vec < _ > = tcx. with_freevars ( node_id, |fv| {
60+ fv. iter ( ) . enumerate ( ) . map ( |( i, _) | ty:: TypeParameterDef {
61+ index : ( base_generics. count ( ) as u32 ) + ( i as u32 ) ,
62+ name : token:: intern ( "<upvar>" ) ,
63+ def_id : def_id,
64+ default_def_id : base_def_id,
65+ default : None ,
66+ object_lifetime_default : ty:: ObjectLifetimeDefault :: BaseDefault ,
67+ pure_wrt_drop : false ,
68+ } ) . collect ( )
69+ } ) ;
70+
71+ tcx. alloc_generics ( ty:: Generics {
72+ parent : Some ( base_def_id) ,
73+ parent_regions : base_generics. parent_regions +
74+ ( base_generics. regions . len ( ) as u32 ) ,
75+ parent_types : base_generics. parent_types +
76+ ( base_generics. types . len ( ) as u32 ) ,
77+ regions : vec ! [ ] ,
78+ types : upvar_decls,
79+ has_self : false ,
80+ } )
81+ } ) ;
82+
83+ tcx. item_types . memoize ( def_id, || tcx. mk_closure ( def_id, Substs :: for_item (
84+ tcx, def_id,
85+ |def, _| tcx. mk_region ( def. to_early_bound_region ( ) ) ,
86+ |def, _| tcx. mk_param_from_def ( def)
87+ ) ) ) ;
88+ }
89+
4690 fn check_closure ( & self ,
4791 expr : & hir:: Expr ,
4892 opt_kind : Option < ty:: ClosureKind > ,
4993 decl : & ' gcx hir:: FnDecl ,
5094 body : & ' gcx hir:: Expr ,
5195 expected_sig : Option < ty:: FnSig < ' tcx > > )
5296 -> Ty < ' tcx > {
53- let expr_def_id = self . tcx . map . local_def_id ( expr. id ) ;
54- let base_def_id = self . tcx . closure_base_def_id ( expr_def_id) ;
55-
5697 debug ! ( "check_closure opt_kind={:?} expected_sig={:?}" ,
5798 opt_kind,
5899 expected_sig) ;
59100
101+ let expr_def_id = self . tcx . map . local_def_id ( expr. id ) ;
102+ self . declare_closure ( expr_def_id) ;
103+
60104 let mut fn_ty = AstConv :: ty_of_closure ( self ,
61105 hir:: Unsafety :: Normal ,
62106 decl,
@@ -66,32 +110,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
66110 // Create type variables (for now) to represent the transformed
67111 // types of upvars. These will be unified during the upvar
68112 // inference phase (`upvar.rs`).
69- let base_generics = self . tcx . item_generics ( base_def_id) ;
70- // provide junk type parameter defs - the only place that
71- // cares about anything but the length is instantiation,
72- // and we don't do that for closures.
73- let upvar_decls : Vec < _ > = self . tcx . with_freevars ( expr. id , |fv| {
74- fv. iter ( ) . enumerate ( ) . map ( |( i, _) | ty:: TypeParameterDef {
75- index : ( base_generics. count ( ) as u32 ) + ( i as u32 ) ,
76- name : token:: intern ( "<upvar>" ) ,
77- def_id : expr_def_id,
78- default_def_id : base_def_id,
79- default : None ,
80- object_lifetime_default : ty:: ObjectLifetimeDefault :: BaseDefault ,
81- pure_wrt_drop : false ,
82- } ) . collect ( )
83- } ) ;
84- let num_upvars = upvar_decls. len ( ) ;
85-
86- self . tcx . generics . memoize ( expr_def_id, || self . tcx . alloc_generics ( ty:: Generics {
87- parent : Some ( base_def_id) ,
88- parent_regions : base_generics. parent_regions + ( base_generics. regions . len ( ) as u32 ) ,
89- parent_types : base_generics. parent_types + ( base_generics. types . len ( ) as u32 ) ,
90- regions : vec ! [ ] ,
91- types : upvar_decls,
92- has_self : false ,
93- } ) ) ;
94-
113+ let num_upvars = self . tcx . with_freevars ( expr. id , |fv| fv. len ( ) ) ;
95114 let upvar_tys = self . next_ty_vars ( num_upvars) ;
96115
97116 debug ! ( "check_closure: expr.id={:?} upvar_tys={:?}" ,
0 commit comments