@@ -19,11 +19,13 @@ use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
1919use  rustc_middle:: hir:: nested_filter; 
2020use  rustc_middle:: middle:: stability:: EvalResult ; 
2121use  rustc_middle:: traits:: DefiningAnchor ; 
22+ use  rustc_middle:: ty:: fold:: BottomUpFolder ; 
2223use  rustc_middle:: ty:: layout:: { LayoutError ,  MAX_SIMD_LANES } ; 
2324use  rustc_middle:: ty:: util:: { Discr ,  IntTypeExt } ; 
2425use  rustc_middle:: ty:: GenericArgKind ; 
2526use  rustc_middle:: ty:: { 
26-     self ,  AdtDef ,  ParamEnv ,  Ty ,  TyCtxt ,  TypeSuperVisitable ,  TypeVisitable ,  TypeVisitableExt , 
27+     self ,  AdtDef ,  ParamEnv ,  RegionKind ,  Ty ,  TyCtxt ,  TypeSuperVisitable ,  TypeVisitable , 
28+     TypeVisitableExt , 
2729} ; 
2830use  rustc_session:: lint:: builtin:: { UNINHABITED_STATIC ,  UNSUPPORTED_CALLING_CONVENTIONS } ; 
2931use  rustc_span:: symbol:: sym; 
@@ -34,6 +36,7 @@ use rustc_trait_selection::traits::error_reporting::on_unimplemented::OnUnimplem
3436use  rustc_trait_selection:: traits:: error_reporting:: TypeErrCtxtExt  as  _; 
3537use  rustc_trait_selection:: traits:: outlives_bounds:: InferCtxtExt  as  _; 
3638use  rustc_trait_selection:: traits:: { self ,  ObligationCtxt ,  TraitEngine ,  TraitEngineExt  as  _} ; 
39+ use  rustc_type_ir:: fold:: TypeFoldable ; 
3740
3841use  std:: ops:: ControlFlow ; 
3942
@@ -437,7 +440,7 @@ fn check_opaque_meets_bounds<'tcx>(
437440    // hidden type is well formed even without those bounds. 
438441    let  predicate =
439442        ty:: Binder :: dummy ( ty:: PredicateKind :: Clause ( ty:: ClauseKind :: WellFormed ( hidden_ty. into ( ) ) ) ) ; 
440-     ocx. register_obligation ( Obligation :: new ( tcx,  misc_cause,  param_env,  predicate) ) ; 
443+     ocx. register_obligation ( Obligation :: new ( tcx,  misc_cause. clone ( ) ,  param_env,  predicate) ) ; 
441444
442445    // Check that all obligations are satisfied by the implementation's 
443446    // version. 
@@ -464,11 +467,179 @@ fn check_opaque_meets_bounds<'tcx>(
464467            ocx. resolve_regions_and_report_errors ( defining_use_anchor,  & outlives_env) ?; 
465468        } 
466469    } 
467-     // Clean up after ourselves 
468-     let  _ = infcx. take_opaque_types ( ) ; 
470+     // Check that any hidden types found during wf checking match the hidden types that `type_of` sees. 
471+     for  ( key,  mut  ty)  in  infcx. take_opaque_types ( )  { 
472+         ty. hidden_type . ty  = infcx. resolve_vars_if_possible ( ty. hidden_type . ty ) ; 
473+         sanity_check_found_hidden_type ( tcx,  key,  ty. hidden_type ,  defining_use_anchor,  origin) ?; 
474+     } 
469475    Ok ( ( ) ) 
470476} 
471477
478+ fn  sanity_check_found_hidden_type < ' tcx > ( 
479+     tcx :  TyCtxt < ' tcx > , 
480+     key :  ty:: OpaqueTypeKey < ' tcx > , 
481+     mut  ty :  ty:: OpaqueHiddenType < ' tcx > , 
482+     defining_use_anchor :  LocalDefId , 
483+     origin :  & hir:: OpaqueTyOrigin , 
484+ )  -> Result < ( ) ,  ErrorGuaranteed >  { 
485+     if  ty. ty . is_ty_var ( )  { 
486+         // Nothing was actually constrained. 
487+         return  Ok ( ( ) ) ; 
488+     } 
489+     if  let  ty:: Alias ( ty:: Opaque ,  alias)  = ty. ty . kind ( )  { 
490+         if  alias. def_id  == key. def_id . to_def_id ( )  && alias. args  == key. args  { 
491+             // Nothing was actually constrained, this is an opaque usage that was 
492+             // only discovered to be opaque after inference vars resolved. 
493+             return  Ok ( ( ) ) ; 
494+         } 
495+     } 
496+     // Closures frequently end up containing erased lifetimes in their final representation. 
497+     // These correspond to lifetime variables that never got resolved, so we patch this up here. 
498+     ty. ty  = ty. ty . fold_with ( & mut  BottomUpFolder  { 
499+         tcx, 
500+         ty_op :  |t| t, 
501+         ct_op :  |c| c, 
502+         lt_op :  |l| match  l. kind ( )  { 
503+             RegionKind :: ReVar ( _)  => tcx. lifetimes . re_erased , 
504+             _ => l, 
505+         } , 
506+     } ) ; 
507+     // Get the hidden type. 
508+     let  mut  hidden_ty = tcx. type_of ( key. def_id ) . instantiate ( tcx,  key. args ) ; 
509+     if  let  hir:: OpaqueTyOrigin :: FnReturn ( ..)  | hir:: OpaqueTyOrigin :: AsyncFn ( ..)  = origin { 
510+         if  hidden_ty != ty. ty  { 
511+             hidden_ty = find_and_apply_rpit_args ( 
512+                 tcx, 
513+                 hidden_ty, 
514+                 defining_use_anchor. to_def_id ( ) , 
515+                 key. def_id . to_def_id ( ) , 
516+             ) ?; 
517+         } 
518+     } 
519+ 
520+     // If the hidden types differ, emit a type mismatch diagnostic. 
521+     if  hidden_ty == ty. ty  { 
522+         Ok ( ( ) ) 
523+     }  else  { 
524+         let  span = tcx. def_span ( key. def_id ) ; 
525+         let  other = ty:: OpaqueHiddenType  {  ty :  hidden_ty,  span } ; 
526+         Err ( ty. report_mismatch ( & other,  key. def_id ,  tcx) . emit ( ) ) 
527+     } 
528+ } 
529+ 
530+ /// In case it is in a nested opaque type, find that opaque type's 
531+ /// usage in the function signature and use the generic arguments from the usage site. 
532+ /// We need to do because RPITs ignore the lifetimes of the function, 
533+ /// as they have their own copies of all the lifetimes they capture. 
534+ /// So the only way to get the lifetimes represented in terms of the function, 
535+ /// is to look how they are used in the function signature (or do some other fancy 
536+ /// recording of this mapping at ast -> hir lowering time). 
537+ /// 
538+ /// As an example: 
539+ /// ```text 
540+ /// trait Id { 
541+ ///     type Assoc; 
542+ /// } 
543+ /// impl<'a> Id for &'a () { 
544+ ///     type Assoc = &'a (); 
545+ /// } 
546+ /// fn func<'a>(x: &'a ()) -> impl Id<Assoc = impl Sized + 'a> { x } 
547+ /// // desugared to 
548+ /// fn func<'a>(x: &'a () -> Outer<'a> where <Outer<'a> as Id>::Assoc = Inner<'a> { 
549+ ///     // Note that in contrast to other nested items, RPIT type aliases can 
550+ ///     // access their parents' generics. 
551+ /// 
552+ ///     // hidden type is `&'aDupOuter ()` 
553+ ///     // During wfcheck the hidden type of `Inner<'aDupOuter>` is `&'a ()`, but 
554+ ///     // `typeof(Inner<'aDupOuter>) = &'aDupOuter ()`. 
555+ ///     // So we walk the signature of `func` to find the use of `Inner<'a>` 
556+ ///     // and then use that to replace the lifetimes in the hidden type, obtaining 
557+ ///     // `&'a ()`. 
558+ ///     type Outer<'aDupOuter> = impl Id<Assoc = Inner<'aDupOuter>>; 
559+ /// 
560+ ///     // hidden type is `&'aDupInner ()` 
561+ ///     type Inner<'aDupInner> = impl Sized + 'aDupInner; 
562+ /// 
563+ ///     x 
564+ /// } 
565+ /// ``` 
566+ fn  find_and_apply_rpit_args < ' tcx > ( 
567+     tcx :  TyCtxt < ' tcx > , 
568+     mut  hidden_ty :  Ty < ' tcx > , 
569+     function :  DefId , 
570+     opaque :  DefId , 
571+ )  -> Result < Ty < ' tcx > ,  ErrorGuaranteed >  { 
572+     // Find use of the RPIT in the function signature and thus find the right args to 
573+     // convert it into the parameter space of the function signature. This is needed, 
574+     // because that's what `type_of` returns, against which we compare later. 
575+     let  ret = tcx. fn_sig ( function) . instantiate_identity ( ) . output ( ) ; 
576+     struct  Visitor < ' tcx >  { 
577+         tcx :  TyCtxt < ' tcx > , 
578+         opaque :  DefId , 
579+         function :  DefId , 
580+         seen :  FxHashSet < DefId > , 
581+     } 
582+     impl < ' tcx >  ty:: TypeVisitor < TyCtxt < ' tcx > >  for  Visitor < ' tcx >  { 
583+         type  BreakTy  = GenericArgsRef < ' tcx > ; 
584+ 
585+         #[ instrument( level = "trace" ,  skip( self ) ,  ret) ]  
586+         fn  visit_ty ( & mut  self ,  t :  Ty < ' tcx > )  -> ControlFlow < Self :: BreakTy >  { 
587+             trace ! ( "{:#?}" ,  t. kind( ) ) ; 
588+             match  t. kind ( )  { 
589+                 ty:: Alias ( ty:: Opaque ,  alias)  => { 
590+                     trace ! ( ?alias. def_id) ; 
591+                     if  alias. def_id  == self . opaque  { 
592+                         return  ControlFlow :: Break ( alias. args ) ; 
593+                     }  else  if  self . seen . insert ( alias. def_id )  { 
594+                         for  clause in  self 
595+                             . tcx 
596+                             . explicit_item_bounds ( alias. def_id ) 
597+                             . iter_instantiated_copied ( self . tcx ,  alias. args ) 
598+                         { 
599+                             trace ! ( ?clause) ; 
600+                             clause. visit_with ( self ) ?; 
601+                         } 
602+                     } 
603+                 } 
604+                 ty:: Alias ( ty:: Projection ,  alias)  => { 
605+                     if  self . tcx . is_impl_trait_in_trait ( alias. def_id ) 
606+                         && self . tcx . impl_trait_in_trait_parent_fn ( alias. def_id )  == self . function 
607+                     { 
608+                         // If we're lowering to associated item, install the opaque type which is just 
609+                         // the `type_of` of the trait's associated item. If we're using the old lowering 
610+                         // strategy, then just reinterpret the associated type like an opaque :^) 
611+                         self . tcx 
612+                             . type_of ( alias. def_id ) 
613+                             . instantiate ( self . tcx ,  alias. args ) 
614+                             . visit_with ( self ) ?; 
615+                     } 
616+                 } 
617+                 ty:: Alias ( ty:: Weak ,  alias)  => { 
618+                     self . tcx 
619+                         . type_of ( alias. def_id ) 
620+                         . instantiate ( self . tcx ,  alias. args ) 
621+                         . visit_with ( self ) ?; 
622+                 } 
623+                 _ => ( ) , 
624+             } 
625+ 
626+             t. super_visit_with ( self ) 
627+         } 
628+     } 
629+     if  let  ControlFlow :: Break ( args)  =
630+         ret. visit_with ( & mut  Visitor  {  tcx,  function,  opaque,  seen :  Default :: default ( )  } ) 
631+     { 
632+         trace ! ( ?args) ; 
633+         trace ! ( "expected: {hidden_ty:#?}" ) ; 
634+         hidden_ty = ty:: EarlyBinder :: bind ( hidden_ty) . instantiate ( tcx,  args) ; 
635+         trace ! ( "expected: {hidden_ty:#?}" ) ; 
636+     }  else  { 
637+         tcx. sess 
638+             . delay_span_bug ( tcx. def_span ( function) ,  format ! ( "{ret:?} does not contain {opaque:?}" ) ) ; 
639+     } 
640+     Ok ( hidden_ty) 
641+ } 
642+ 
472643fn  is_enum_of_nonnullable_ptr < ' tcx > ( 
473644    tcx :  TyCtxt < ' tcx > , 
474645    adt_def :  AdtDef < ' tcx > , 
0 commit comments