@@ -184,16 +184,17 @@ impl<'db> ConstraintSet<'db> {
184184
185185 /// Updates this set to be the union of itself and a clause.
186186 fn union_clause ( & mut self , db : & ' db dyn Db , clause : ConstraintClause < ' db > ) {
187- for existing in & mut self . clauses {
188- // If there is an existing constraint set that subsumes (or is subsumed by) the new
189- // one, we want to keep the _subsumed_ constraint set.
190- if clause. subsumes ( db, existing) {
191- return ;
192- } else if existing. subsumes ( db, & clause) {
193- * existing = clause;
194- return ;
195- }
187+ // If there is an existing clause that is subsumed by (i.e., is bigger than) the new one,
188+ // then the new clause doesn't provide any useful additional information, and we don't have
189+ // to add it.
190+ if ( self . clauses . iter ( ) ) . any ( |existing| clause. subsumes ( db, existing) ) {
191+ return ;
196192 }
193+
194+ // If there are any existing clauses that subsume (i.e., are smaller than) the new one, we
195+ // should delete them, since the new clause provides strictly more useful information.
196+ self . clauses
197+ . retain ( |existing| !existing. subsumes ( db, & clause) ) ;
197198 self . clauses . push ( clause) ;
198199 }
199200
@@ -251,9 +252,7 @@ impl<'db> Constraints<'db> for ConstraintSet<'db> {
251252 }
252253}
253254
254- /// A set of merged constraints, representing the intersection of those constraints. We guarantee
255- /// that no constraint in the set subsumes another, and that no two constraints in the set have the
256- /// same typevar.
255+ /// The intersection of a list of atomic constraints.
257256///
258257/// This is called a "constraint set", and denoted _C_, in [[POPL2015][]].
259258///
@@ -280,8 +279,7 @@ impl<'db> ConstraintClause<'db> {
280279 }
281280 }
282281
283- /// Adds a new constraint to this clause, ensuring that no constraint in the clause subsumes
284- /// another, and that no two constraints in the set have the same typevar. Because atomic
282+ /// Returns the intersection of this clause and an atomic constraint. Because atomic
285283 /// constraints can be negated, the intersection of the new and existing atomic constraints
286284 /// (for the same typevar) might be the union of two atomic constraints.
287285 fn intersect_constraint (
0 commit comments