@@ -7,6 +7,7 @@ use crate::rustc_middle::ty::subst::Subst;
77use rustc_hir as hir;
88use rustc_hir:: def_id:: DefId ;
99use rustc_hir:: lang_items:: LangItem ;
10+ use rustc_infer:: infer:: opaque_types:: ReplaceOpaqueTypes ;
1011use rustc_infer:: infer:: type_variable:: { TypeVariableOrigin , TypeVariableOriginKind } ;
1112use rustc_infer:: infer:: LateBoundRegionConversionTime ;
1213use rustc_infer:: infer:: { InferOk , InferResult } ;
@@ -645,13 +646,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
645646 result
646647 }
647648
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.
648653 fn hide_parent_opaque_types ( & self , ty : Ty < ' tcx > , span : Span , body_id : hir:: HirId ) -> Ty < ' tcx > {
649654 let InferOk { value, obligations } = self . replace_opaque_types_with_inference_vars (
650655 ty,
651656 body_id,
652657 span,
653658 ObligationCauseCode :: MiscObligation ,
654659 self . param_env ,
660+ ReplaceOpaqueTypes :: OnlyForRPIT ,
655661 ) ;
656662 self . register_predicates ( obligations) ;
657663 value
@@ -671,39 +677,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
671677
672678 let ret_ty = ret_coercion. borrow ( ) . expected_ty ( ) ;
673679 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 ) ) ,
676711 ty:: Error ( _) => return None ,
677712 _ => span_bug ! (
678713 self . tcx. def_span( expr_def_id) ,
679714 "async fn generator return type not an inference variable"
680715 ) ,
681716 } ;
682717
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-
707718 debug ! ( "deduce_future_output_from_obligations: output_ty={:?}" , output_ty) ;
708719 output_ty
709720 }
0 commit comments