@@ -7,6 +7,7 @@ use crate::rustc_middle::ty::subst::Subst;
7
7
use rustc_hir as hir;
8
8
use rustc_hir:: def_id:: DefId ;
9
9
use rustc_hir:: lang_items:: LangItem ;
10
+ use rustc_infer:: infer:: opaque_types:: ReplaceOpaqueTypes ;
10
11
use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
11
12
use rustc_infer:: infer:: LateBoundRegionConversionTime ;
12
13
use rustc_infer:: infer:: { InferOk , InferResult } ;
@@ -645,13 +646,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
645
646
result
646
647
}
647
648
649
+ /// Closures can't create hidden types for opaque types of their parent, as they
650
+ /// do not have all the outlives information available. Also `type_of` looks for
651
+ /// hidden types in the owner (so the closure's parent), so it would not find these
652
+ /// definitions.
648
653
fn hide_parent_opaque_types ( & self , ty : Ty < ' tcx > , span : Span , body_id : hir:: HirId ) -> Ty < ' tcx > {
649
654
let InferOk { value, obligations } = self . replace_opaque_types_with_inference_vars (
650
655
ty,
651
656
body_id,
652
657
span,
653
658
ObligationCauseCode :: MiscObligation ,
654
659
self . param_env ,
660
+ ReplaceOpaqueTypes :: OnlyForRPIT ,
655
661
) ;
656
662
self . register_predicates ( obligations) ;
657
663
value
@@ -671,39 +677,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
671
677
672
678
let ret_ty = ret_coercion. borrow ( ) . expected_ty ( ) ;
673
679
let ret_ty = self . inh . infcx . shallow_resolve ( ret_ty) ;
674
- let ( def_id, substs) = match * ret_ty. kind ( ) {
675
- ty:: Opaque ( def_id, substs) => ( def_id, substs) ,
680
+
681
+ let get_future_output = |predicate : ty:: Predicate < ' tcx > , span| {
682
+ // Search for a pending obligation like
683
+ //
684
+ // `<R as Future>::Output = T`
685
+ //
686
+ // where R is the return type we are expecting. This type `T`
687
+ // will be our output.
688
+ let bound_predicate = predicate. kind ( ) ;
689
+ if let ty:: PredicateKind :: Projection ( proj_predicate) = bound_predicate. skip_binder ( ) {
690
+ self . deduce_future_output_from_projection (
691
+ span,
692
+ bound_predicate. rebind ( proj_predicate) ,
693
+ )
694
+ } else {
695
+ None
696
+ }
697
+ } ;
698
+
699
+ let output_ty = match * ret_ty. kind ( ) {
700
+ ty:: Infer ( ty:: TyVar ( ret_vid) ) => {
701
+ self . obligations_for_self_ty ( ret_vid) . find_map ( |( _, obligation) | {
702
+ get_future_output ( obligation. predicate , obligation. cause . span )
703
+ } )
704
+ }
705
+ ty:: Opaque ( def_id, substs) => self
706
+ . tcx
707
+ . bound_explicit_item_bounds ( def_id)
708
+ . transpose_iter ( )
709
+ . map ( |e| e. map_bound ( |e| * e) . transpose_tuple2 ( ) )
710
+ . find_map ( |( p, s) | get_future_output ( p. subst ( self . tcx , substs) , s. 0 ) ) ,
676
711
ty:: Error ( _) => return None ,
677
712
_ => span_bug ! (
678
713
self . tcx. def_span( expr_def_id) ,
679
714
"async fn generator return type not an inference variable"
680
715
) ,
681
716
} ;
682
717
683
- let item_bounds = self . tcx . bound_explicit_item_bounds ( def_id) ;
684
-
685
- // Search for a pending obligation like
686
- //
687
- // `<R as Future>::Output = T`
688
- //
689
- // where R is the return type we are expecting. This type `T`
690
- // will be our output.
691
- let output_ty = item_bounds
692
- . transpose_iter ( )
693
- . map ( |e| e. map_bound ( |e| * e) . transpose_tuple2 ( ) )
694
- . find_map ( |( predicate, span) | {
695
- let bound_predicate = predicate. subst ( self . tcx , substs) . kind ( ) ;
696
- if let ty:: PredicateKind :: Projection ( proj_predicate) = bound_predicate. skip_binder ( )
697
- {
698
- self . deduce_future_output_from_projection (
699
- span. 0 ,
700
- bound_predicate. rebind ( proj_predicate) ,
701
- )
702
- } else {
703
- None
704
- }
705
- } ) ;
706
-
707
718
debug ! ( "deduce_future_output_from_obligations: output_ty={:?}" , output_ty) ;
708
719
output_ty
709
720
}
0 commit comments