@@ -13,7 +13,7 @@ use rustc_hir::intravisit::Visitor;
13
13
use rustc_hir:: { ItemKind , Node , PathSegment } ;
14
14
use rustc_infer:: infer:: opaque_types:: ConstrainOpaqueTypeRegionVisitor ;
15
15
use rustc_infer:: infer:: outlives:: env:: OutlivesEnvironment ;
16
- use rustc_infer:: infer:: { RegionVariableOrigin , TyCtxtInferExt } ;
16
+ use rustc_infer:: infer:: { LateBoundRegionConversionTime , RegionVariableOrigin , TyCtxtInferExt } ;
17
17
use rustc_infer:: traits:: { Obligation , TraitEngineExt as _} ;
18
18
use rustc_lint_defs:: builtin:: REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS ;
19
19
use rustc_middle:: hir:: nested_filter;
@@ -407,7 +407,38 @@ 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 mut args = GenericArgs :: identity_for_item ( tcx, def_id. to_def_id ( ) ) ;
411
+ assert ! ( !args. has_escaping_bound_vars( ) , "{args:#?}" ) ;
412
+ if let hir:: OpaqueTyOrigin :: FnReturn ( ..) | hir:: OpaqueTyOrigin :: AsyncFn ( ..) = origin {
413
+ // Find use of the RPIT in the function signature and thus find the right args to
414
+ // convert it into the parameter space of the function signature. This is needed,
415
+ // because that's what `type_of` returns, against which we compare later.
416
+ let ret = tcx. fn_sig ( defining_use_anchor) . instantiate_identity ( ) . output ( ) ;
417
+
418
+ let a = ret
419
+ . skip_binder ( )
420
+ . visit_with ( & mut FindOpaqueTypeArgs {
421
+ tcx,
422
+ opaque : def_id. to_def_id ( ) ,
423
+ fn_def_id : defining_use_anchor. to_def_id ( ) ,
424
+ seen : Default :: default ( ) ,
425
+ depth : ty:: INNERMOST ,
426
+ } )
427
+ . break_value ( )
428
+ . ok_or_else ( || {
429
+ tcx. sess . delay_span_bug (
430
+ tcx. def_span ( defining_use_anchor) ,
431
+ format ! ( "return type of {defining_use_anchor:?} does not contain {def_id:?}" ) ,
432
+ )
433
+ } ) ?;
434
+ let a = infcx. instantiate_binder_with_fresh_vars (
435
+ span,
436
+ LateBoundRegionConversionTime :: HigherRankedType ,
437
+ ret. rebind ( a) ,
438
+ ) ;
439
+ assert ! ( !a. has_escaping_bound_vars( ) , "{a:#?}" ) ;
440
+ args = ty:: EarlyBinder :: bind ( args) . instantiate ( tcx, a) ;
441
+ }
411
442
let opaque_ty = Ty :: new_opaque ( tcx, def_id. to_def_id ( ) , args) ;
412
443
413
444
// `ReErased` regions appear in the "parent_args" of closures/generators.
@@ -468,9 +499,10 @@ fn check_opaque_meets_bounds<'tcx>(
468
499
}
469
500
}
470
501
// 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 ( ) {
502
+ for ( mut key, mut ty) in infcx. take_opaque_types ( ) {
472
503
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) ?;
504
+ key = infcx. resolve_vars_if_possible ( key) ;
505
+ sanity_check_found_hidden_type ( tcx, key, ty. hidden_type ) ?;
474
506
}
475
507
Ok ( ( ) )
476
508
}
@@ -479,8 +511,6 @@ fn sanity_check_found_hidden_type<'tcx>(
479
511
tcx : TyCtxt < ' tcx > ,
480
512
key : ty:: OpaqueTypeKey < ' tcx > ,
481
513
mut ty : ty:: OpaqueHiddenType < ' tcx > ,
482
- defining_use_anchor : LocalDefId ,
483
- origin : & hir:: OpaqueTyOrigin ,
484
514
) -> Result < ( ) , ErrorGuaranteed > {
485
515
if ty. ty . is_ty_var ( ) {
486
516
// Nothing was actually constrained.
@@ -493,29 +523,23 @@ fn sanity_check_found_hidden_type<'tcx>(
493
523
return Ok ( ( ) ) ;
494
524
}
495
525
}
526
+ let strip_vars = |ty : Ty < ' tcx > | {
527
+ ty. fold_with ( & mut BottomUpFolder {
528
+ tcx,
529
+ ty_op : |t| t,
530
+ ct_op : |c| c,
531
+ lt_op : |l| match l. kind ( ) {
532
+ RegionKind :: ReVar ( _) => tcx. lifetimes . re_erased ,
533
+ _ => l,
534
+ } ,
535
+ } )
536
+ } ;
496
537
// Closures frequently end up containing erased lifetimes in their final representation.
497
538
// 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
- } ) ;
539
+ ty. ty = strip_vars ( ty. ty ) ;
507
540
// 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
- }
541
+ let hidden_ty = tcx. type_of ( key. def_id ) . instantiate ( tcx, key. args ) ;
542
+ let hidden_ty = strip_vars ( hidden_ty) ;
519
543
520
544
// If the hidden types differ, emit a type mismatch diagnostic.
521
545
if hidden_ty == ty. ty {
@@ -563,67 +587,80 @@ fn sanity_check_found_hidden_type<'tcx>(
563
587
/// x
564
588
/// }
565
589
/// ```
566
- fn find_and_apply_rpit_args < ' tcx > (
590
+ struct FindOpaqueTypeArgs < ' tcx > {
567
591
tcx : TyCtxt < ' tcx > ,
568
- mut hidden_ty : Ty < ' tcx > ,
569
- function : DefId ,
570
592
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 > ,
593
+ seen : FxHashSet < DefId > ,
594
+ fn_def_id : DefId ,
595
+ depth : ty:: DebruijnIndex ,
596
+ }
597
+ impl < ' tcx > ty:: TypeVisitor < TyCtxt < ' tcx > > for FindOpaqueTypeArgs < ' tcx > {
598
+ type BreakTy = GenericArgsRef < ' tcx > ;
599
+
600
+ #[ instrument( level = "trace" , skip( self ) , ret) ]
601
+ fn visit_binder < T : TypeVisitable < TyCtxt < ' tcx > > > (
602
+ & mut self ,
603
+ t : & ty:: Binder < ' tcx , T > ,
604
+ ) -> ControlFlow < Self :: BreakTy > {
605
+ self . depth . shift_in ( 1 ) ;
606
+ let binder = t. super_visit_with ( self ) ;
607
+ self . depth . shift_out ( 1 ) ;
608
+ binder
580
609
}
581
- impl < ' tcx > ty:: TypeVisitor < TyCtxt < ' tcx > > for Visitor < ' tcx > {
582
- type BreakTy = GenericArgsRef < ' tcx > ;
583
610
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 ) ?;
611
+ #[ instrument( level = "trace" , skip( self ) , ret) ]
612
+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
613
+ trace ! ( "{:#?}" , t. kind( ) ) ;
614
+ match t. kind ( ) {
615
+ ty:: Alias ( ty:: Opaque , alias) => {
616
+ trace ! ( ?alias. def_id) ;
617
+ if alias. def_id == self . opaque {
618
+ let args = self . tcx . fold_regions ( alias. args , |re, depth| {
619
+ if let ty:: ReLateBound ( index, bv) = re. kind ( ) {
620
+ if depth != ty:: INNERMOST {
621
+ return ty:: Region :: new_error_with_message (
622
+ self . tcx ,
623
+ self . tcx . def_span ( self . opaque ) ,
624
+ "opaque type behind meaningful binders are not supported yet" ,
625
+ ) ;
626
+ }
627
+ ty:: Region :: new_late_bound (
628
+ self . tcx ,
629
+ index. shifted_out_to_binder ( self . depth ) ,
630
+ bv,
631
+ )
632
+ } else {
633
+ re
600
634
}
635
+ } ) ;
636
+ return ControlFlow :: Break ( args) ;
637
+ } else if self . seen . insert ( alias. def_id ) {
638
+ for clause in self
639
+ . tcx
640
+ . explicit_item_bounds ( alias. def_id )
641
+ . iter_instantiated_copied ( self . tcx , alias. args )
642
+ {
643
+ trace ! ( ?clause) ;
644
+ clause. visit_with ( self ) ?;
601
645
}
602
646
}
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 ) ?;
647
+ }
648
+ ty:: Alias ( ty:: Projection , alias) => {
649
+ if let Some ( ty:: ImplTraitInTraitData :: Trait { fn_def_id, .. } ) = self . tcx . opt_rpitit_info ( alias. def_id ) && fn_def_id == self . fn_def_id {
650
+ self . tcx . type_of ( alias. def_id ) . instantiate ( self . tcx , alias. args ) . visit_with ( self ) ?;
608
651
}
609
- _ => ( ) ,
610
652
}
611
-
612
- t. super_visit_with ( self )
653
+ ty:: Alias ( ty:: Weak , alias) => {
654
+ self . tcx
655
+ . type_of ( alias. def_id )
656
+ . instantiate ( self . tcx , alias. args )
657
+ . visit_with ( self ) ?;
658
+ }
659
+ _ => ( ) ,
613
660
}
661
+
662
+ t. super_visit_with ( self )
614
663
}
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
664
}
628
665
629
666
fn is_enum_of_nonnullable_ptr < ' tcx > (
0 commit comments