|
26 | 26 | //! constraint set implementation, and the `bool` impl of the trait (and possibly the trait itself) |
27 | 27 | //! will go away. |
28 | 28 |
|
| 29 | +use std::fmt::Display; |
| 30 | + |
29 | 31 | use smallvec::{SmallVec, smallvec}; |
30 | 32 |
|
31 | 33 | use crate::Db; |
@@ -82,6 +84,9 @@ pub(crate) trait Constraints<'db>: Clone + Sized { |
82 | 84 | } |
83 | 85 | self |
84 | 86 | } |
| 87 | + |
| 88 | + #[allow(dead_code)] |
| 89 | + fn display(&self, db: &'db dyn Db) -> impl Display; |
85 | 90 | } |
86 | 91 |
|
87 | 92 | /// An extension trait for building constraint sets from [`Option`] values. |
@@ -214,6 +219,31 @@ impl<'db> ConstraintSet<'db> { |
214 | 219 | } |
215 | 220 | } |
216 | 221 | } |
| 222 | + |
| 223 | + #[allow(dead_code)] |
| 224 | + pub(crate) fn display(&self, db: &'db dyn Db) -> impl Display { |
| 225 | + struct DisplayConstraintSet<'a, 'db> { |
| 226 | + set: &'a ConstraintSet<'db>, |
| 227 | + db: &'db dyn Db, |
| 228 | + } |
| 229 | + |
| 230 | + impl Display for DisplayConstraintSet<'_, '_> { |
| 231 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 232 | + if self.set.clauses.is_empty() { |
| 233 | + return f.write_str("0"); |
| 234 | + } |
| 235 | + for (i, clause) in self.set.clauses.iter().enumerate() { |
| 236 | + if i > 0 { |
| 237 | + f.write_str(" ∨ ")?; |
| 238 | + } |
| 239 | + clause.display(self.db).fmt(f)?; |
| 240 | + } |
| 241 | + Ok(()) |
| 242 | + } |
| 243 | + } |
| 244 | + |
| 245 | + DisplayConstraintSet { set: self, db } |
| 246 | + } |
217 | 247 | } |
218 | 248 |
|
219 | 249 | impl<'db> Constraints<'db> for ConstraintSet<'db> { |
@@ -250,6 +280,10 @@ impl<'db> Constraints<'db> for ConstraintSet<'db> { |
250 | 280 | } |
251 | 281 | result |
252 | 282 | } |
| 283 | + |
| 284 | + fn display(&self, db: &'db dyn Db) -> impl Display { |
| 285 | + self.display(db) |
| 286 | + } |
253 | 287 | } |
254 | 288 |
|
255 | 289 | /// The intersection of a list of atomic constraints. |
@@ -381,6 +415,37 @@ impl<'db> ConstraintClause<'db> { |
381 | 415 | } |
382 | 416 | result |
383 | 417 | } |
| 418 | + |
| 419 | + fn display(&self, db: &'db dyn Db) -> impl Display { |
| 420 | + struct DisplayConstraintClause<'a, 'db> { |
| 421 | + clause: &'a ConstraintClause<'db>, |
| 422 | + db: &'db dyn Db, |
| 423 | + } |
| 424 | + |
| 425 | + impl Display for DisplayConstraintClause<'_, '_> { |
| 426 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 427 | + if self.clause.constraints.is_empty() { |
| 428 | + return f.write_str("1"); |
| 429 | + } |
| 430 | + |
| 431 | + if self.clause.constraints.len() > 1 { |
| 432 | + f.write_str("(")?; |
| 433 | + } |
| 434 | + for (i, constraint) in self.clause.constraints.iter().enumerate() { |
| 435 | + if i > 0 { |
| 436 | + f.write_str(" ∧ ")?; |
| 437 | + } |
| 438 | + constraint.display(self.db).fmt(f)?; |
| 439 | + } |
| 440 | + if self.clause.constraints.len() > 1 { |
| 441 | + f.write_str(")")?; |
| 442 | + } |
| 443 | + Ok(()) |
| 444 | + } |
| 445 | + } |
| 446 | + |
| 447 | + DisplayConstraintClause { clause: self, db } |
| 448 | + } |
384 | 449 | } |
385 | 450 |
|
386 | 451 | /// A constraint on a single typevar. |
@@ -597,6 +662,35 @@ impl<'db> AtomicConstraint<'db> { |
597 | 662 | ), |
598 | 663 | } |
599 | 664 | } |
| 665 | + |
| 666 | + fn display(self, db: &'db dyn Db) -> impl Display { |
| 667 | + struct DisplayAtomicConstraint<'db> { |
| 668 | + constraint: AtomicConstraint<'db>, |
| 669 | + db: &'db dyn Db, |
| 670 | + } |
| 671 | + |
| 672 | + impl Display for DisplayAtomicConstraint<'_> { |
| 673 | + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 674 | + if self.constraint.sign == ConstraintSign::Negative { |
| 675 | + f.write_str("¬")?; |
| 676 | + } |
| 677 | + f.write_str("(")?; |
| 678 | + if !self.constraint.lower.is_never() { |
| 679 | + write!(f, "{} ≤ ", self.constraint.lower.display(self.db))?; |
| 680 | + } |
| 681 | + self.constraint.typevar.display(self.db).fmt(f)?; |
| 682 | + if !self.constraint.upper.is_object(self.db) { |
| 683 | + write!(f, " ≤ {}", self.constraint.lower.display(self.db))?; |
| 684 | + } |
| 685 | + f.write_str(")") |
| 686 | + } |
| 687 | + } |
| 688 | + |
| 689 | + DisplayAtomicConstraint { |
| 690 | + constraint: self, |
| 691 | + db, |
| 692 | + } |
| 693 | + } |
600 | 694 | } |
601 | 695 |
|
602 | 696 | #[derive(Clone, Copy, Debug)] |
|
0 commit comments