@@ -68,12 +68,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
6868
6969 debug ! ( ?bound_sig, ?liberated_sig) ;
7070
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+
7179 // FIXME: We could probably actually just unify this further --
7280 // instead of having a `FnSig` and a `Option<CoroutineTypes>`,
7381 // we can have a `ClosureSignature { Coroutine { .. }, Closure { .. } }`,
7482 // 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+ }
77123 hir:: ClosureKind :: Coroutine ( kind) => {
78124 let yield_ty = match kind {
79125 hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Gen , _)
@@ -119,74 +165,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
119165 // Resume type defaults to `()` if the coroutine has no argument.
120166 let resume_ty = liberated_sig. inputs ( ) . get ( 0 ) . copied ( ) . unwrap_or ( tcx. types . unit ) ;
121167
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- } ;
190168 let interior = self . next_ty_var ( TypeVariableOrigin {
191169 kind : TypeVariableOriginKind :: MiscVariable ,
192170 span : body. value . span ,
@@ -209,9 +187,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
209187 } ,
210188 ) ;
211189
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+ )
213194 }
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
215209 }
216210
217211 /// Given the expected type, figures out what it can about this closure we
@@ -683,10 +677,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
683677 } )
684678 }
685679 // 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 ,
690684
691685 // For async blocks, we just fall back to `_` here.
692686 // For closures/coroutines, we know nothing about the return
0 commit comments