@@ -407,7 +407,17 @@ fn check_opaque_meets_bounds<'tcx>(
407
407
. build ( ) ;
408
408
let ocx = ObligationCtxt :: new ( & infcx) ;
409
409
410
- let args = GenericArgs :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ;
410
+ let args = match * origin {
411
+ hir:: OpaqueTyOrigin :: FnReturn ( parent) | hir:: OpaqueTyOrigin :: AsyncFn ( parent) => {
412
+ GenericArgs :: identity_for_item ( tcx, parent) . extend_to (
413
+ tcx,
414
+ def_id. to_def_id ( ) ,
415
+ |param, _| tcx. map_rpit_lifetime_to_fn_lifetime ( param. def_id . expect_local ( ) ) . into ( ) ,
416
+ )
417
+ }
418
+ hir:: OpaqueTyOrigin :: TyAlias { .. } => GenericArgs :: identity_for_item ( tcx, def_id) ,
419
+ } ;
420
+
411
421
let opaque_ty = Ty :: new_opaque ( tcx, def_id. to_def_id ( ) , args) ;
412
422
413
423
// `ReErased` regions appear in the "parent_args" of closures/generators.
@@ -468,9 +478,10 @@ fn check_opaque_meets_bounds<'tcx>(
468
478
}
469
479
}
470
480
// 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 ( ) {
481
+ for ( mut key, mut ty) in infcx. take_opaque_types ( ) {
472
482
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) ?;
483
+ key = infcx. resolve_vars_if_possible ( key) ;
484
+ sanity_check_found_hidden_type ( tcx, key, ty. hidden_type ) ?;
474
485
}
475
486
Ok ( ( ) )
476
487
}
@@ -479,8 +490,6 @@ fn sanity_check_found_hidden_type<'tcx>(
479
490
tcx : TyCtxt < ' tcx > ,
480
491
key : ty:: OpaqueTypeKey < ' tcx > ,
481
492
mut ty : ty:: OpaqueHiddenType < ' tcx > ,
482
- defining_use_anchor : LocalDefId ,
483
- origin : & hir:: OpaqueTyOrigin ,
484
493
) -> Result < ( ) , ErrorGuaranteed > {
485
494
if ty. ty . is_ty_var ( ) {
486
495
// Nothing was actually constrained.
@@ -493,29 +502,23 @@ fn sanity_check_found_hidden_type<'tcx>(
493
502
return Ok ( ( ) ) ;
494
503
}
495
504
}
505
+ let strip_vars = |ty : Ty < ' tcx > | {
506
+ ty. fold_with ( & mut BottomUpFolder {
507
+ tcx,
508
+ ty_op : |t| t,
509
+ ct_op : |c| c,
510
+ lt_op : |l| match l. kind ( ) {
511
+ RegionKind :: ReVar ( _) => tcx. lifetimes . re_erased ,
512
+ _ => l,
513
+ } ,
514
+ } )
515
+ } ;
496
516
// Closures frequently end up containing erased lifetimes in their final representation.
497
517
// 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
- } ) ;
518
+ ty. ty = strip_vars ( ty. ty ) ;
507
519
// 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
- }
520
+ let hidden_ty = tcx. type_of ( key. def_id ) . instantiate ( tcx, key. args ) ;
521
+ let hidden_ty = strip_vars ( hidden_ty) ;
519
522
520
523
// If the hidden types differ, emit a type mismatch diagnostic.
521
524
if hidden_ty == ty. ty {
@@ -527,105 +530,6 @@ fn sanity_check_found_hidden_type<'tcx>(
527
530
}
528
531
}
529
532
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
- seen : FxHashSet < DefId > ,
580
- }
581
- impl < ' tcx > ty:: TypeVisitor < TyCtxt < ' tcx > > for Visitor < ' tcx > {
582
- type BreakTy = GenericArgsRef < ' tcx > ;
583
-
584
- #[ instrument( level = "trace" , skip( self ) , ret) ]
585
- fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
586
- trace ! ( "{:#?}" , t. kind( ) ) ;
587
- match t. kind ( ) {
588
- ty:: Alias ( ty:: Opaque , alias) => {
589
- trace ! ( ?alias. def_id) ;
590
- if alias. def_id == self . opaque {
591
- return ControlFlow :: Break ( alias. args ) ;
592
- } else if self . seen . insert ( alias. def_id ) {
593
- for clause in self
594
- . tcx
595
- . explicit_item_bounds ( alias. def_id )
596
- . iter_instantiated_copied ( self . tcx , alias. args )
597
- {
598
- trace ! ( ?clause) ;
599
- clause. visit_with ( self ) ?;
600
- }
601
- }
602
- }
603
- ty:: Alias ( ty:: Weak , alias) => {
604
- self . tcx
605
- . type_of ( alias. def_id )
606
- . instantiate ( self . tcx , alias. args )
607
- . visit_with ( self ) ?;
608
- }
609
- _ => ( ) ,
610
- }
611
-
612
- t. super_visit_with ( self )
613
- }
614
- }
615
- if let ControlFlow :: Break ( args) =
616
- ret. visit_with ( & mut Visitor { tcx, opaque, seen : Default :: default ( ) } )
617
- {
618
- trace ! ( ?args) ;
619
- trace ! ( "expected: {hidden_ty:#?}" ) ;
620
- hidden_ty = ty:: EarlyBinder :: bind ( hidden_ty) . instantiate ( tcx, args) ;
621
- trace ! ( "expected: {hidden_ty:#?}" ) ;
622
- } else {
623
- tcx. sess
624
- . delay_span_bug ( tcx. def_span ( function) , format ! ( "{ret:?} does not contain {opaque:?}" ) ) ;
625
- }
626
- Ok ( hidden_ty)
627
- }
628
-
629
533
fn is_enum_of_nonnullable_ptr < ' tcx > (
630
534
tcx : TyCtxt < ' tcx > ,
631
535
adt_def : AdtDef < ' tcx > ,
0 commit comments