@@ -293,7 +293,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
293
293
let gen_trait = tcx. lang_items ( ) . gen_trait ( ) ;
294
294
let is_gen = gen_trait == Some ( trait_def_id) ;
295
295
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) {
297
300
debug ! ( "not fn or generator" ) ;
298
301
return None ;
299
302
}
@@ -305,6 +308,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
305
308
return None ;
306
309
}
307
310
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
+
308
316
let input_tys = if is_fn {
309
317
let arg_param_ty = projection. skip_binder ( ) . projection_ty . substs . type_at ( 1 ) ;
310
318
let arg_param_ty = self . resolve_vars_if_possible ( arg_param_ty) ;
@@ -314,17 +322,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
314
322
& ty:: Tuple ( tys) => tys,
315
323
_ => return None ,
316
324
}
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 ( ) ) ] )
317
340
} else {
318
341
// Generators with a `()` resume type may be defined with 0 or 1 explicit arguments,
319
342
// else they must have exactly 1 argument. For now though, just give up in this case.
320
343
return None ;
321
344
} ;
322
345
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
-
328
346
let sig = projection. rebind ( self . tcx . mk_fn_sig (
329
347
input_tys,
330
348
ret_param_ty,
0 commit comments