@@ -634,6 +634,42 @@ impl<'tcx> TyCtxt<'tcx> {
634634 . 0
635635 }
636636
637+ pub fn shift_bound_var_indices < T > ( self , bound_vars : usize , value : T ) -> T
638+ where
639+ T : TypeFoldable < ' tcx > ,
640+ {
641+ self . replace_escaping_bound_vars (
642+ value,
643+ |r| {
644+ self . mk_region ( ty:: ReLateBound (
645+ ty:: INNERMOST ,
646+ ty:: BoundRegion {
647+ var : ty:: BoundVar :: from_usize ( r. var . as_usize ( ) + bound_vars) ,
648+ kind : r. kind ,
649+ } ,
650+ ) )
651+ } ,
652+ |t| {
653+ self . mk_ty ( ty:: Bound (
654+ ty:: INNERMOST ,
655+ ty:: BoundTy {
656+ var : ty:: BoundVar :: from_usize ( t. var . as_usize ( ) + bound_vars) ,
657+ kind : t. kind ,
658+ } ,
659+ ) )
660+ } ,
661+ |c, ty| {
662+ self . mk_const ( ty:: Const {
663+ val : ty:: ConstKind :: Bound (
664+ ty:: INNERMOST ,
665+ ty:: BoundVar :: from_usize ( c. as_usize ( ) + bound_vars) ,
666+ ) ,
667+ ty,
668+ } )
669+ } ,
670+ )
671+ }
672+
637673 /// Returns a set of all late-bound regions that are constrained
638674 /// by `value`, meaning that if we instantiate those LBR with
639675 /// variables and equate `value` with something else, those
@@ -695,16 +731,21 @@ impl<'tcx> TyCtxt<'tcx> {
695731 T : TypeFoldable < ' tcx > ,
696732 {
697733 let mut counter = 0 ;
698- Binder :: bind (
699- self . replace_late_bound_regions ( sig, |_| {
700- let br = ty:: BoundRegion { kind : ty:: BrAnon ( counter) } ;
734+ let inner = self
735+ . replace_late_bound_regions ( sig, |_| {
736+ let br = ty:: BoundRegion {
737+ var : ty:: BoundVar :: from_u32 ( counter) ,
738+ kind : ty:: BrAnon ( counter) ,
739+ } ;
701740 let r = self . mk_region ( ty:: ReLateBound ( ty:: INNERMOST , br) ) ;
702741 counter += 1 ;
703742 r
704743 } )
705- . 0 ,
706- self ,
707- )
744+ . 0 ;
745+ let bound_vars = self . mk_bound_variable_kinds (
746+ ( 0 ..counter) . map ( |i| ty:: BoundVariableKind :: Region ( ty:: BrAnon ( i) ) ) ,
747+ ) ;
748+ Binder :: bind_with_vars ( inner, bound_vars)
708749 }
709750}
710751
@@ -777,27 +818,105 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
777818 }
778819
779820 fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
780- use std:: collections:: btree_map:: Entry ;
781821 match r {
782- ty:: ReLateBound ( index, br) if * index == self . binder_index => match br. kind {
783- ty:: BrNamed ( _def_id, _name) => {
784- // FIXME
785- }
822+ ty:: ReLateBound ( index, _br) if * index == self . binder_index => {
823+ bug ! ( "{:?} {:?}" , index, _br)
824+ }
786825
787- ty:: BrAnon ( var) => match self . vars . entry ( var) {
788- Entry :: Vacant ( entry) => {
789- entry. insert ( ty:: BoundVariableKind :: Region ( br. kind ) ) ;
826+ _ => ( ) ,
827+ } ;
828+
829+ r. super_visit_with ( self )
830+ }
831+ }
832+
833+ pub struct ValidateBoundVars < ' tcx > {
834+ bound_vars : & ' tcx ty:: List < ty:: BoundVariableKind > ,
835+ binder_index : ty:: DebruijnIndex ,
836+ // We may encounter the same variable at different levels of binding, so
837+ // this can't just be `Ty`
838+ visited : SsoHashSet < ( ty:: DebruijnIndex , Ty < ' tcx > ) > ,
839+ }
840+
841+ impl < ' tcx > ValidateBoundVars < ' tcx > {
842+ pub fn new ( bound_vars : & ' tcx ty:: List < ty:: BoundVariableKind > ) -> Self {
843+ ValidateBoundVars {
844+ bound_vars,
845+ binder_index : ty:: INNERMOST ,
846+ visited : SsoHashSet :: default ( ) ,
847+ }
848+ }
849+ }
850+
851+ impl < ' tcx > TypeVisitor < ' tcx > for ValidateBoundVars < ' tcx > {
852+ type BreakTy = ( ) ;
853+
854+ fn visit_binder < T : TypeFoldable < ' tcx > > (
855+ & mut self ,
856+ t : & Binder < ' tcx , T > ,
857+ ) -> ControlFlow < Self :: BreakTy > {
858+ self . binder_index . shift_in ( 1 ) ;
859+ let result = t. super_visit_with ( self ) ;
860+ self . binder_index . shift_out ( 1 ) ;
861+ result
862+ }
863+
864+ fn visit_ty ( & mut self , t : Ty < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
865+ if t. outer_exclusive_binder < self . binder_index
866+ || !self . visited . insert ( ( self . binder_index , t) )
867+ {
868+ return ControlFlow :: BREAK ;
869+ }
870+ match * t. kind ( ) {
871+ ty:: Bound ( debruijn, bound_ty) if debruijn == self . binder_index => {
872+ if self . bound_vars . len ( ) <= bound_ty. var . as_usize ( ) {
873+ panic ! ( "Not enough bound vars: {:?} not found in {:?}" , t, self . bound_vars) ;
874+ }
875+ let list_var = self . bound_vars [ bound_ty. var . as_usize ( ) ] ;
876+ match list_var {
877+ ty:: BoundVariableKind :: Ty ( kind) => {
878+ if kind != bound_ty. kind {
879+ panic ! (
880+ "Mismatched type kinds: {:?} doesn't var in list {:?}" ,
881+ bound_ty. kind, list_var
882+ ) ;
883+ }
790884 }
791- Entry :: Occupied ( entry) => match entry. get ( ) {
792- ty:: BoundVariableKind :: Region ( _) => { }
793- _ => bug ! ( "Conflicting bound vars" ) ,
794- } ,
795- } ,
885+ _ => panic ! (
886+ "Mismatched bound variable kinds! Expected type, found {:?}" ,
887+ list_var
888+ ) ,
889+ }
890+ }
891+
892+ _ => ( ) ,
893+ } ;
894+
895+ t. super_visit_with ( self )
896+ }
796897
797- ty:: BrEnv => {
798- // FIXME
898+ fn visit_region ( & mut self , r : ty:: Region < ' tcx > ) -> ControlFlow < Self :: BreakTy > {
899+ match r {
900+ ty:: ReLateBound ( index, br) if * index == self . binder_index => {
901+ if self . bound_vars . len ( ) <= br. var . as_usize ( ) {
902+ panic ! ( "Not enough bound vars: {:?} not found in {:?}" , * br, self . bound_vars) ;
799903 }
800- } ,
904+ let list_var = self . bound_vars [ br. var . as_usize ( ) ] ;
905+ match list_var {
906+ ty:: BoundVariableKind :: Region ( kind) => {
907+ if kind != br. kind {
908+ panic ! (
909+ "Mismatched region kinds: {:?} doesn't match var ({:?}) in list ({:?})" ,
910+ br. kind, list_var, self . bound_vars
911+ ) ;
912+ }
913+ }
914+ _ => panic ! (
915+ "Mismatched bound variable kinds! Expected region, found {:?}" ,
916+ list_var
917+ ) ,
918+ }
919+ }
801920
802921 _ => ( ) ,
803922 } ;
0 commit comments