@@ -409,6 +409,10 @@ impl<'db> ConstraintSet<'db> {
409409 Self { node }
410410 }
411411
412+ pub ( crate ) fn for_each_path ( self , db : & ' db dyn Db , f : impl FnMut ( & PathAssignments < ' db > ) ) {
413+ self . node . for_each_path ( db, f) ;
414+ }
415+
412416 pub ( crate ) fn range (
413417 db : & ' db dyn Db ,
414418 lower : Type < ' db > ,
@@ -448,9 +452,9 @@ impl<'db> BoundTypeVarInstance<'db> {
448452/// lower and upper bound.
449453#[ salsa:: interned( debug, heap_size=ruff_memory_usage:: heap_size) ]
450454pub ( crate ) struct ConstrainedTypeVar < ' db > {
451- typevar : BoundTypeVarInstance < ' db > ,
452- lower : Type < ' db > ,
453- upper : Type < ' db > ,
455+ pub ( crate ) typevar : BoundTypeVarInstance < ' db > ,
456+ pub ( crate ) lower : Type < ' db > ,
457+ pub ( crate ) upper : Type < ' db > ,
454458}
455459
456460// The Salsa heap is tracked separately.
@@ -659,7 +663,7 @@ impl<'db> ConstrainedTypeVar<'db> {
659663 Some ( Self :: new ( db, self . typevar ( db) , lower, upper) )
660664 }
661665
662- fn display ( self , db : & ' db dyn Db ) -> impl Display {
666+ pub ( crate ) fn display ( self , db : & ' db dyn Db ) -> impl Display {
663667 self . display_inner ( db, false )
664668 }
665669
@@ -825,6 +829,40 @@ impl<'db> Node<'db> {
825829 }
826830 }
827831
832+ fn for_each_path ( self , db : & ' db dyn Db , mut f : impl FnMut ( & PathAssignments < ' db > ) ) {
833+ match self {
834+ Node :: AlwaysTrue => { }
835+ Node :: AlwaysFalse => { }
836+ Node :: Interior ( interior) => {
837+ let map = interior. sequent_map ( db) ;
838+ let mut path = PathAssignments :: default ( ) ;
839+ self . for_each_path_inner ( db, & mut f, map, & mut path) ;
840+ }
841+ }
842+ }
843+
844+ fn for_each_path_inner (
845+ self ,
846+ db : & ' db dyn Db ,
847+ f : & mut dyn FnMut ( & PathAssignments < ' db > ) ,
848+ map : & SequentMap < ' db > ,
849+ path : & mut PathAssignments < ' db > ,
850+ ) {
851+ match self {
852+ Node :: AlwaysTrue => f ( path) ,
853+ Node :: AlwaysFalse => { }
854+ Node :: Interior ( interior) => {
855+ let constraint = interior. constraint ( db) ;
856+ path. walk_edge ( map, constraint. when_true ( ) , |path, _| {
857+ interior. if_true ( db) . for_each_path_inner ( db, f, map, path) ;
858+ } ) ;
859+ path. walk_edge ( map, constraint. when_false ( ) , |path, _| {
860+ interior. if_false ( db) . for_each_path_inner ( db, f, map, path) ;
861+ } ) ;
862+ }
863+ }
864+ }
865+
828866 /// Returns whether this BDD represent the constant function `true`.
829867 fn is_always_satisfied ( self , db : & ' db dyn Db ) -> bool {
830868 match self {
@@ -2147,7 +2185,7 @@ fn sequent_map_cycle_initial<'db>(
21472185/// An assignment of one BDD variable to either `true` or `false`. (When evaluating a BDD, we
21482186/// must provide an assignment for each variable present in the BDD.)
21492187#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
2150- enum ConstraintAssignment < ' db > {
2188+ pub ( crate ) enum ConstraintAssignment < ' db > {
21512189 Positive ( ConstrainedTypeVar < ' db > ) ,
21522190 Negative ( ConstrainedTypeVar < ' db > ) ,
21532191}
@@ -2227,7 +2265,7 @@ impl<'db> ConstraintAssignment<'db> {
22272265 // Keep this for future debugging needs, even though it's not currently used when rendering
22282266 // constraint sets.
22292267 #[ expect( dead_code) ]
2230- fn display ( self , db : & ' db dyn Db ) -> impl Display {
2268+ pub ( crate ) fn display ( self , db : & ' db dyn Db ) -> impl Display {
22312269 struct DisplayConstraintAssignment < ' db > {
22322270 constraint : ConstraintAssignment < ' db > ,
22332271 db : & ' db dyn Db ,
@@ -2694,7 +2732,7 @@ impl<'db> SequentMap<'db> {
26942732/// The collection of constraints that we know to be true or false at a certain point when
26952733/// traversing a BDD.
26962734#[ derive( Debug , Default ) ]
2697- struct PathAssignments < ' db > {
2735+ pub ( crate ) struct PathAssignments < ' db > {
26982736 assignments : FxOrderSet < ConstraintAssignment < ' db > > ,
26992737}
27002738
@@ -2753,6 +2791,17 @@ impl<'db> PathAssignments<'db> {
27532791 result
27542792 }
27552793
2794+ pub ( crate ) fn positive_constraints (
2795+ & self ,
2796+ ) -> impl Iterator < Item = ConstrainedTypeVar < ' db > > + ' _ {
2797+ self . assignments
2798+ . iter ( )
2799+ . filter_map ( |assignment| match assignment {
2800+ ConstraintAssignment :: Positive ( constraint) => Some ( * constraint) ,
2801+ ConstraintAssignment :: Negative ( _) => None ,
2802+ } )
2803+ }
2804+
27562805 fn assignment_holds ( & self , assignment : ConstraintAssignment < ' db > ) -> bool {
27572806 self . assignments . contains ( & assignment)
27582807 }
0 commit comments