13
13
use super :: { check_fn, Expectation , FnCtxt } ;
14
14
15
15
use astconv:: AstConv ;
16
+ use rustc:: hir:: def_id:: DefId ;
16
17
use rustc:: ty:: { self , ToPolyTraitRef , Ty } ;
18
+ use rustc:: ty:: subst:: Substs ;
17
19
use rustc:: util:: common:: MemoizationMap ;
18
20
use std:: cmp;
19
21
use syntax:: abi:: Abi ;
@@ -43,20 +45,62 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
43
45
self . check_closure ( expr, expected_kind, decl, body, expected_sig)
44
46
}
45
47
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
+
46
90
fn check_closure ( & self ,
47
91
expr : & hir:: Expr ,
48
92
opt_kind : Option < ty:: ClosureKind > ,
49
93
decl : & ' gcx hir:: FnDecl ,
50
94
body : & ' gcx hir:: Expr ,
51
95
expected_sig : Option < ty:: FnSig < ' tcx > > )
52
96
-> 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
-
56
97
debug ! ( "check_closure opt_kind={:?} expected_sig={:?}" ,
57
98
opt_kind,
58
99
expected_sig) ;
59
100
101
+ let expr_def_id = self . tcx . map . local_def_id ( expr. id ) ;
102
+ self . declare_closure ( expr_def_id) ;
103
+
60
104
let mut fn_ty = AstConv :: ty_of_closure ( self ,
61
105
hir:: Unsafety :: Normal ,
62
106
decl,
@@ -66,32 +110,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
66
110
// Create type variables (for now) to represent the transformed
67
111
// types of upvars. These will be unified during the upvar
68
112
// 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 ( ) ) ;
95
114
let upvar_tys = self . next_ty_vars ( num_upvars) ;
96
115
97
116
debug ! ( "check_closure: expr.id={:?} upvar_tys={:?}" ,
0 commit comments