@@ -4,6 +4,7 @@ use crate::traits;
4
4
use hir:: def:: DefKind ;
5
5
use hir:: def_id:: { DefId , LocalDefId } ;
6
6
use hir:: { HirId , OpaqueTyOrigin } ;
7
+ use rustc_data_structures:: fx:: FxHashSet ;
7
8
use rustc_data_structures:: sync:: Lrc ;
8
9
use rustc_data_structures:: vec_map:: VecMap ;
9
10
use rustc_hir as hir;
@@ -16,7 +17,6 @@ use rustc_middle::ty::{
16
17
} ;
17
18
use rustc_middle:: ty:: { DefIdTree , GenericArgKind } ;
18
19
use rustc_span:: Span ;
19
- use smallvec:: SmallVec ;
20
20
21
21
use std:: ops:: ControlFlow ;
22
22
@@ -673,29 +673,37 @@ pub fn may_define_opaque_type<'tcx>(
673
673
struct Visitor < ' tcx > {
674
674
opaque_def_id : DefId ,
675
675
tcx : TyCtxt < ' tcx > ,
676
- ignore_nested : SmallVec < [ DefId ; 1 ] > ,
676
+ seen : FxHashSet < Ty < ' tcx > > ,
677
677
param_env : ty:: ParamEnv < ' tcx > ,
678
678
}
679
679
impl < ' tcx > TypeVisitor < ' tcx > for Visitor < ' tcx > {
680
680
type BreakTy = ( ) ;
681
+
681
682
#[ instrument( skip( self ) , level = "trace" , ret) ]
682
683
fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
684
+ // Erase all lifetimes, they can't affect anything, but recursion
685
+ // may cause late bound regions to differ, because the type visitor
686
+ // can't erase them in `visit_binder`.
687
+ let t = t. fold_with ( & mut BottomUpFolder {
688
+ tcx : self . tcx ,
689
+ ct_op : |c| c,
690
+ ty_op : |t| t,
691
+ lt_op : |_| self . tcx . lifetimes . re_erased ,
692
+ } ) ;
693
+ if !self . seen . insert ( t) {
694
+ return ControlFlow :: Continue ( ( ) ) ;
695
+ }
683
696
match t. kind ( ) {
684
697
ty:: Alias ( ty:: Opaque , alias) => {
685
698
if alias. def_id == self . opaque_def_id {
686
699
return ControlFlow :: Break ( ( ) ) ;
687
700
}
688
- if !self . ignore_nested . contains ( & alias. def_id ) {
689
- // avoid infinite recursion since the opaque type shows
690
- // up in its own bounds.
691
- self . ignore_nested . push ( alias. def_id ) ;
692
- for ( pred, _span) in self
693
- . tcx
694
- . bound_explicit_item_bounds ( alias. def_id )
695
- . subst_iter_copied ( self . tcx , alias. substs )
696
- {
697
- pred. visit_with ( self ) ?;
698
- }
701
+ for ( pred, _span) in self
702
+ . tcx
703
+ . bound_explicit_item_bounds ( alias. def_id )
704
+ . subst_iter_copied ( self . tcx , alias. substs )
705
+ {
706
+ pred. visit_with ( self ) ?;
699
707
}
700
708
}
701
709
ty:: Alias ( ty:: Projection , _) => {
@@ -708,14 +716,9 @@ pub fn may_define_opaque_type<'tcx>(
708
716
// Types that have opaque type fields must get walked manually, they
709
717
// would not be seen by the type visitor otherwise.
710
718
ty:: Adt ( adt_def, substs) => {
711
- if !self . ignore_nested . contains ( & adt_def. did ( ) ) {
712
- // avoid infinite recursion since adts can recursively refer
713
- // to themselves
714
- self . ignore_nested . push ( adt_def. did ( ) ) ;
715
- for variant in adt_def. variants ( ) {
716
- for field in & variant. fields {
717
- field. ty ( self . tcx , substs) . visit_with ( self ) ?;
718
- }
719
+ for variant in adt_def. variants ( ) {
720
+ for field in & variant. fields {
721
+ field. ty ( self . tcx , substs) . visit_with ( self ) ?;
719
722
}
720
723
}
721
724
}
@@ -727,7 +730,7 @@ pub fn may_define_opaque_type<'tcx>(
727
730
val. visit_with ( & mut Visitor {
728
731
opaque_def_id : opaque_def_id. to_def_id ( ) ,
729
732
tcx,
730
- ignore_nested : SmallVec :: new ( ) ,
733
+ seen : Default :: default ( ) ,
731
734
param_env,
732
735
} )
733
736
. is_break ( )
0 commit comments