Skip to content

Commit f06c0f6

Browse files
committed
display impl for constraint sets
1 parent ae2bf01 commit f06c0f6

File tree

2 files changed

+122
-8
lines changed

2 files changed

+122
-8
lines changed

crates/ty_python_semantic/src/types/constraints.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
//! constraint set implementation, and the `bool` impl of the trait (and possibly the trait itself)
2727
//! will go away.
2828
29+
use std::fmt::Display;
30+
2931
use smallvec::{SmallVec, smallvec};
3032

3133
use crate::Db;
@@ -82,6 +84,9 @@ pub(crate) trait Constraints<'db>: Clone + Sized {
8284
}
8385
self
8486
}
87+
88+
#[allow(dead_code)]
89+
fn display(&self, db: &'db dyn Db) -> impl Display;
8590
}
8691

8792
/// An extension trait for building constraint sets from [`Option`] values.
@@ -214,6 +219,31 @@ impl<'db> ConstraintSet<'db> {
214219
}
215220
}
216221
}
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+
}
217247
}
218248

219249
impl<'db> Constraints<'db> for ConstraintSet<'db> {
@@ -250,6 +280,10 @@ impl<'db> Constraints<'db> for ConstraintSet<'db> {
250280
}
251281
result
252282
}
283+
284+
fn display(&self, db: &'db dyn Db) -> impl Display {
285+
self.display(db)
286+
}
253287
}
254288

255289
/// The intersection of a list of atomic constraints.
@@ -381,6 +415,37 @@ impl<'db> ConstraintClause<'db> {
381415
}
382416
result
383417
}
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+
}
384449
}
385450

386451
/// A constraint on a single typevar.
@@ -597,6 +662,35 @@ impl<'db> AtomicConstraint<'db> {
597662
),
598663
}
599664
}
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+
}
600694
}
601695

602696
#[derive(Clone, Copy, Debug)]

crates/ty_python_semantic/src/types/display.rs

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use crate::types::generics::{GenericContext, Specialization};
1414
use crate::types::signatures::{CallableSignature, Parameter, Parameters, Signature};
1515
use crate::types::tuple::TupleSpec;
1616
use crate::types::{
17-
CallableType, IntersectionType, KnownClass, MethodWrapperKind, Protocol, StringLiteralType,
18-
SubclassOfInner, Type, UnionType, WrapperDescriptorKind,
17+
BoundTypeVarInstance, CallableType, IntersectionType, KnownClass, MethodWrapperKind, Protocol,
18+
StringLiteralType, SubclassOfInner, Type, UnionType, WrapperDescriptorKind,
1919
};
2020

2121
/// Settings for displaying types and signatures
@@ -279,12 +279,7 @@ impl Display for DisplayRepresentation<'_> {
279279
)
280280
}
281281
Type::NonInferableTypeVar(bound_typevar) | Type::TypeVar(bound_typevar) => {
282-
f.write_str(bound_typevar.typevar(self.db).name(self.db))?;
283-
if let Some(binding_context) = bound_typevar.binding_context(self.db).name(self.db)
284-
{
285-
write!(f, "@{binding_context}")?;
286-
}
287-
Ok(())
282+
bound_typevar.display(self.db).fmt(f)
288283
}
289284
Type::AlwaysTruthy => f.write_str("AlwaysTruthy"),
290285
Type::AlwaysFalsy => f.write_str("AlwaysFalsy"),
@@ -318,6 +313,31 @@ impl Display for DisplayRepresentation<'_> {
318313
}
319314
}
320315

316+
impl<'db> BoundTypeVarInstance<'db> {
317+
#[allow(dead_code)]
318+
pub(crate) fn display(self, db: &'db dyn Db) -> impl Display {
319+
DisplayBoundTypeVarInstance {
320+
bound_typevar: self,
321+
db,
322+
}
323+
}
324+
}
325+
326+
struct DisplayBoundTypeVarInstance<'db> {
327+
bound_typevar: BoundTypeVarInstance<'db>,
328+
db: &'db dyn Db,
329+
}
330+
331+
impl Display for DisplayBoundTypeVarInstance<'_> {
332+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
333+
f.write_str(self.bound_typevar.typevar(self.db).name(self.db))?;
334+
if let Some(binding_context) = self.bound_typevar.binding_context(self.db).name(self.db) {
335+
write!(f, "@{binding_context}")?;
336+
}
337+
Ok(())
338+
}
339+
}
340+
321341
impl<'db> TupleSpec<'db> {
322342
pub(crate) fn display_with(
323343
&'db self,

0 commit comments

Comments
 (0)