@@ -68,12 +68,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
68
68
69
69
debug ! ( ?bound_sig, ?liberated_sig) ;
70
70
71
+ let parent_args =
72
+ GenericArgs :: identity_for_item ( tcx, tcx. typeck_root_def_id ( expr_def_id. to_def_id ( ) ) ) ;
73
+
74
+ let tupled_upvars_ty = self . next_root_ty_var ( TypeVariableOrigin {
75
+ kind : TypeVariableOriginKind :: ClosureSynthetic ,
76
+ span : expr_span,
77
+ } ) ;
78
+
71
79
// FIXME: We could probably actually just unify this further --
72
80
// instead of having a `FnSig` and a `Option<CoroutineTypes>`,
73
81
// we can have a `ClosureSignature { Coroutine { .. }, Closure { .. } }`,
74
82
// similar to how `ty::GenSig` is a distinct data structure.
75
- let coroutine_types = match closure. kind {
76
- hir:: ClosureKind :: Closure => None ,
83
+ let ( closure_ty, coroutine_types) = match closure. kind {
84
+ hir:: ClosureKind :: Closure => {
85
+ // Tuple up the arguments and insert the resulting function type into
86
+ // the `closures` table.
87
+ let sig = bound_sig. map_bound ( |sig| {
88
+ tcx. mk_fn_sig (
89
+ [ Ty :: new_tup ( tcx, sig. inputs ( ) ) ] ,
90
+ sig. output ( ) ,
91
+ sig. c_variadic ,
92
+ sig. unsafety ,
93
+ sig. abi ,
94
+ )
95
+ } ) ;
96
+
97
+ debug ! ( ?sig, ?expected_kind) ;
98
+
99
+ let closure_kind_ty = match expected_kind {
100
+ Some ( kind) => Ty :: from_closure_kind ( tcx, kind) ,
101
+
102
+ // Create a type variable (for now) to represent the closure kind.
103
+ // It will be unified during the upvar inference phase (`upvar.rs`)
104
+ None => self . next_root_ty_var ( TypeVariableOrigin {
105
+ // FIXME(eddyb) distinguish closure kind inference variables from the rest.
106
+ kind : TypeVariableOriginKind :: ClosureSynthetic ,
107
+ span : expr_span,
108
+ } ) ,
109
+ } ;
110
+
111
+ let closure_args = ty:: ClosureArgs :: new (
112
+ tcx,
113
+ ty:: ClosureArgsParts {
114
+ parent_args,
115
+ closure_kind_ty,
116
+ closure_sig_as_fn_ptr_ty : Ty :: new_fn_ptr ( tcx, sig) ,
117
+ tupled_upvars_ty,
118
+ } ,
119
+ ) ;
120
+
121
+ ( Ty :: new_closure ( tcx, expr_def_id. to_def_id ( ) , closure_args. args ) , None )
122
+ }
77
123
hir:: ClosureKind :: Coroutine ( kind) => {
78
124
let yield_ty = match kind {
79
125
hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Gen , _)
@@ -119,74 +165,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
119
165
// Resume type defaults to `()` if the coroutine has no argument.
120
166
let resume_ty = liberated_sig. inputs ( ) . get ( 0 ) . copied ( ) . unwrap_or ( tcx. types . unit ) ;
121
167
122
- Some ( CoroutineTypes { resume_ty, yield_ty } )
123
- }
124
- } ;
125
-
126
- check_fn (
127
- & mut FnCtxt :: new ( self , self . param_env , closure. def_id ) ,
128
- liberated_sig,
129
- coroutine_types,
130
- closure. fn_decl ,
131
- expr_def_id,
132
- body,
133
- // Closure "rust-call" ABI doesn't support unsized params
134
- false ,
135
- ) ;
136
-
137
- let parent_args =
138
- GenericArgs :: identity_for_item ( tcx, tcx. typeck_root_def_id ( expr_def_id. to_def_id ( ) ) ) ;
139
-
140
- let tupled_upvars_ty = self . next_root_ty_var ( TypeVariableOrigin {
141
- kind : TypeVariableOriginKind :: ClosureSynthetic ,
142
- span : expr_span,
143
- } ) ;
144
-
145
- match closure. kind {
146
- hir:: ClosureKind :: Closure => {
147
- assert_eq ! ( coroutine_types, None ) ;
148
- // Tuple up the arguments and insert the resulting function type into
149
- // the `closures` table.
150
- let sig = bound_sig. map_bound ( |sig| {
151
- tcx. mk_fn_sig (
152
- [ Ty :: new_tup ( tcx, sig. inputs ( ) ) ] ,
153
- sig. output ( ) ,
154
- sig. c_variadic ,
155
- sig. unsafety ,
156
- sig. abi ,
157
- )
158
- } ) ;
159
-
160
- debug ! ( ?sig, ?expected_kind) ;
161
-
162
- let closure_kind_ty = match expected_kind {
163
- Some ( kind) => Ty :: from_closure_kind ( tcx, kind) ,
164
-
165
- // Create a type variable (for now) to represent the closure kind.
166
- // It will be unified during the upvar inference phase (`upvar.rs`)
167
- None => self . next_root_ty_var ( TypeVariableOrigin {
168
- // FIXME(eddyb) distinguish closure kind inference variables from the rest.
169
- kind : TypeVariableOriginKind :: ClosureSynthetic ,
170
- span : expr_span,
171
- } ) ,
172
- } ;
173
-
174
- let closure_args = ty:: ClosureArgs :: new (
175
- tcx,
176
- ty:: ClosureArgsParts {
177
- parent_args,
178
- closure_kind_ty,
179
- closure_sig_as_fn_ptr_ty : Ty :: new_fn_ptr ( tcx, sig) ,
180
- tupled_upvars_ty,
181
- } ,
182
- ) ;
183
-
184
- Ty :: new_closure ( tcx, expr_def_id. to_def_id ( ) , closure_args. args )
185
- }
186
- hir:: ClosureKind :: Coroutine ( _) => {
187
- let Some ( CoroutineTypes { resume_ty, yield_ty } ) = coroutine_types else {
188
- bug ! ( "expected coroutine to have yield/resume types" ) ;
189
- } ;
190
168
let interior = self . next_ty_var ( TypeVariableOrigin {
191
169
kind : TypeVariableOriginKind :: MiscVariable ,
192
170
span : body. value . span ,
@@ -209,9 +187,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
209
187
} ,
210
188
) ;
211
189
212
- Ty :: new_coroutine ( tcx, expr_def_id. to_def_id ( ) , coroutine_args. args )
190
+ (
191
+ Ty :: new_coroutine ( tcx, expr_def_id. to_def_id ( ) , coroutine_args. args ) ,
192
+ Some ( CoroutineTypes { resume_ty, yield_ty } ) ,
193
+ )
213
194
}
214
- }
195
+ } ;
196
+
197
+ check_fn (
198
+ & mut FnCtxt :: new ( self , self . param_env , closure. def_id ) ,
199
+ liberated_sig,
200
+ coroutine_types,
201
+ closure. fn_decl ,
202
+ expr_def_id,
203
+ body,
204
+ // Closure "rust-call" ABI doesn't support unsized params
205
+ false ,
206
+ ) ;
207
+
208
+ closure_ty
215
209
}
216
210
217
211
/// Given the expected type, figures out what it can about this closure we
@@ -683,10 +677,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
683
677
} )
684
678
}
685
679
// All `gen {}` and `async gen {}` must return unit.
686
- hir:: ClosureKind :: Coroutine (
687
- hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Gen , _ )
688
- | hir :: CoroutineKind :: Desugared ( hir :: CoroutineDesugaring :: AsyncGen , _ ) ,
689
- ) => self . tcx . types . unit ,
680
+ hir:: ClosureKind :: Coroutine ( hir :: CoroutineKind :: Desugared (
681
+ hir:: CoroutineDesugaring :: Gen | hir:: CoroutineDesugaring :: AsyncGen ,
682
+ _ ,
683
+ ) ) => self . tcx . types . unit ,
690
684
691
685
// For async blocks, we just fall back to `_` here.
692
686
// For closures/coroutines, we know nothing about the return
0 commit comments