@@ -72,7 +72,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
7272 opt_kind : Option < ty:: ClosureKind > ,
7373 expected_sig : Option < ExpectedSig < ' tcx > > ,
7474 ) -> Ty < ' tcx > {
75- let body = self . tcx . hir ( ) . body ( closure. body ) ;
75+ let tcx = self . tcx ;
76+ let body = tcx. hir ( ) . body ( closure. body ) ;
7677
7778 trace ! ( "decl = {:#?}" , closure. fn_decl) ;
7879 let expr_def_id = closure. def_id ;
@@ -83,26 +84,79 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
8384
8485 debug ! ( ?bound_sig, ?liberated_sig) ;
8586
87+ // FIXME: We could probably actually just unify this further --
88+ // instead of having a `FnSig` and a `Option<CoroutineTypes>`,
89+ // we can have a `ClosureSignature { Coroutine { .. }, Closure { .. } }`,
90+ // similar to how `ty::GenSig` is a distinct data structure.
91+ let coroutine_types = match closure. kind {
92+ hir:: ClosureKind :: Closure => None ,
93+ hir:: ClosureKind :: Coroutine ( kind) => {
94+ let yield_ty = match kind {
95+ hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Gen , _)
96+ | hir:: CoroutineKind :: Coroutine ( _) => {
97+ let yield_ty = self . next_ty_var ( TypeVariableOrigin {
98+ kind : TypeVariableOriginKind :: TypeInference ,
99+ span : expr_span,
100+ } ) ;
101+ self . require_type_is_sized ( yield_ty, expr_span, traits:: SizedYieldType ) ;
102+ yield_ty
103+ }
104+ // HACK(-Ztrait-solver=next): In the *old* trait solver, we must eagerly
105+ // guide inference on the yield type so that we can handle `AsyncIterator`
106+ // in this block in projection correctly. In the new trait solver, it is
107+ // not a problem.
108+ hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: AsyncGen , _) => {
109+ let yield_ty = self . next_ty_var ( TypeVariableOrigin {
110+ kind : TypeVariableOriginKind :: TypeInference ,
111+ span : expr_span,
112+ } ) ;
113+ self . require_type_is_sized ( yield_ty, expr_span, traits:: SizedYieldType ) ;
114+
115+ Ty :: new_adt (
116+ tcx,
117+ tcx. adt_def (
118+ tcx. require_lang_item ( hir:: LangItem :: Poll , Some ( expr_span) ) ,
119+ ) ,
120+ tcx. mk_args ( & [ Ty :: new_adt (
121+ tcx,
122+ tcx. adt_def (
123+ tcx. require_lang_item ( hir:: LangItem :: Option , Some ( expr_span) ) ,
124+ ) ,
125+ tcx. mk_args ( & [ yield_ty. into ( ) ] ) ,
126+ )
127+ . into ( ) ] ) ,
128+ )
129+ }
130+ hir:: CoroutineKind :: Desugared ( hir:: CoroutineDesugaring :: Async , _) => {
131+ tcx. types . unit
132+ }
133+ } ;
134+
135+ // Resume type defaults to `()` if the coroutine has no argument.
136+ let resume_ty = liberated_sig. inputs ( ) . get ( 0 ) . copied ( ) . unwrap_or ( tcx. types . unit ) ;
137+
138+ Some ( CoroutineTypes { resume_ty, yield_ty } )
139+ }
140+ } ;
141+
86142 let mut fcx = FnCtxt :: new ( self , self . param_env , closure. def_id ) ;
87- let coroutine_types = check_fn (
143+ check_fn (
88144 & mut fcx,
89145 liberated_sig,
146+ coroutine_types,
90147 closure. fn_decl ,
91148 expr_def_id,
92149 body,
93- Some ( closure. kind ) ,
94150 // Closure "rust-call" ABI doesn't support unsized params
95151 false ,
96152 ) ;
97153
98- let parent_args = GenericArgs :: identity_for_item (
99- self . tcx ,
100- self . tcx . typeck_root_def_id ( expr_def_id. to_def_id ( ) ) ,
101- ) ;
154+ let parent_args =
155+ GenericArgs :: identity_for_item ( tcx, tcx. typeck_root_def_id ( expr_def_id. to_def_id ( ) ) ) ;
102156
103157 let tupled_upvars_ty = self . next_root_ty_var ( TypeVariableOrigin {
104158 kind : TypeVariableOriginKind :: ClosureSynthetic ,
105- span : self . tcx . def_span ( expr_def_id ) ,
159+ span : expr_span ,
106160 } ) ;
107161
108162 match closure. kind {
@@ -111,8 +165,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
111165 // Tuple up the arguments and insert the resulting function type into
112166 // the `closures` table.
113167 let sig = bound_sig. map_bound ( |sig| {
114- self . tcx . mk_fn_sig (
115- [ Ty :: new_tup ( self . tcx , sig. inputs ( ) ) ] ,
168+ tcx. mk_fn_sig (
169+ [ Ty :: new_tup ( tcx, sig. inputs ( ) ) ] ,
116170 sig. output ( ) ,
117171 sig. c_variadic ,
118172 sig. unsafety ,
@@ -123,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
123177 debug ! ( ?sig, ?opt_kind) ;
124178
125179 let closure_kind_ty = match opt_kind {
126- Some ( kind) => Ty :: from_closure_kind ( self . tcx , kind) ,
180+ Some ( kind) => Ty :: from_closure_kind ( tcx, kind) ,
127181
128182 // Create a type variable (for now) to represent the closure kind.
129183 // It will be unified during the upvar inference phase (`upvar.rs`)
@@ -135,16 +189,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
135189 } ;
136190
137191 let closure_args = ty:: ClosureArgs :: new (
138- self . tcx ,
192+ tcx,
139193 ty:: ClosureArgsParts {
140194 parent_args,
141195 closure_kind_ty,
142- closure_sig_as_fn_ptr_ty : Ty :: new_fn_ptr ( self . tcx , sig) ,
196+ closure_sig_as_fn_ptr_ty : Ty :: new_fn_ptr ( tcx, sig) ,
143197 tupled_upvars_ty,
144198 } ,
145199 ) ;
146200
147- Ty :: new_closure ( self . tcx , expr_def_id. to_def_id ( ) , closure_args. args )
201+ Ty :: new_closure ( tcx, expr_def_id. to_def_id ( ) , closure_args. args )
148202 }
149203 hir:: ClosureKind :: Coroutine ( _) => {
150204 let Some ( CoroutineTypes { resume_ty, yield_ty } ) = coroutine_types else {
@@ -161,7 +215,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
161215 ) ) ;
162216
163217 let coroutine_args = ty:: CoroutineArgs :: new (
164- self . tcx ,
218+ tcx,
165219 ty:: CoroutineArgsParts {
166220 parent_args,
167221 resume_ty,
@@ -172,7 +226,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
172226 } ,
173227 ) ;
174228
175- Ty :: new_coroutine ( self . tcx , expr_def_id. to_def_id ( ) , coroutine_args. args )
229+ Ty :: new_coroutine ( tcx, expr_def_id. to_def_id ( ) , coroutine_args. args )
176230 }
177231 }
178232 }
0 commit comments