@@ -293,7 +293,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
293293 let gen_trait = tcx. lang_items ( ) . gen_trait ( ) ;
294294 let is_gen = gen_trait == Some ( trait_def_id) ;
295295
296- if !is_fn && !is_gen {
296+ let future_trait = tcx. lang_items ( ) . future_trait ( ) ;
297+ let is_future = future_trait == Some ( trait_def_id) ;
298+
299+ if !( is_fn || is_gen || is_future) {
297300 debug ! ( "not fn or generator" ) ;
298301 return None ;
299302 }
@@ -305,6 +308,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
305308 return None ;
306309 }
307310
311+ // Since this is a return parameter type it is safe to unwrap.
312+ let ret_param_ty = projection. skip_binder ( ) . term . ty ( ) . unwrap ( ) ;
313+ let ret_param_ty = self . resolve_vars_if_possible ( ret_param_ty) ;
314+ debug ! ( ?ret_param_ty) ;
315+
308316 let input_tys = if is_fn {
309317 let arg_param_ty = projection. skip_binder ( ) . projection_ty . substs . type_at ( 1 ) ;
310318 let arg_param_ty = self . resolve_vars_if_possible ( arg_param_ty) ;
@@ -314,17 +322,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
314322 & ty:: Tuple ( tys) => tys,
315323 _ => return None ,
316324 }
325+ } else if is_future {
326+ // HACK: Skip infer vars to `ui/generic-associated-types/issue-89008.rs` pass.
327+ // Otherwise, we end up with inferring the closure signature to be
328+ // `fn() -> Empty<Repr>` instead of `fn() -> Self::LineStream<'a, Repr>` and
329+ // opaque type inference gets bungled. Similarly, skip opaques, because we don't
330+ // replace them with infer vars, and opaque type inference gets bungled in
331+ // `async fn ..() -> impl Trait {}` cases.
332+ if ret_param_ty. is_ty_var ( ) || ret_param_ty. has_opaque_types ( ) {
333+ return None ;
334+ }
335+
336+ let resume_ty_def_id = self . tcx . require_lang_item ( hir:: LangItem :: ResumeTy , cause_span) ;
337+ self . tcx . mk_type_list ( & [ self
338+ . tcx
339+ . mk_adt ( self . tcx . adt_def ( resume_ty_def_id) , ty:: List :: empty ( ) ) ] )
317340 } else {
318341 // Generators with a `()` resume type may be defined with 0 or 1 explicit arguments,
319342 // else they must have exactly 1 argument. For now though, just give up in this case.
320343 return None ;
321344 } ;
322345
323- // Since this is a return parameter type it is safe to unwrap.
324- let ret_param_ty = projection. skip_binder ( ) . term . ty ( ) . unwrap ( ) ;
325- let ret_param_ty = self . resolve_vars_if_possible ( ret_param_ty) ;
326- debug ! ( ?ret_param_ty) ;
327-
328346 let sig = projection. rebind ( self . tcx . mk_fn_sig (
329347 input_tys,
330348 ret_param_ty,
0 commit comments