Skip to content

Conversation

@dcreager
Copy link
Member

We were previously normalizing the upper and lower bounds of each constraint when constructing constraint sets. Like in #21463, this was for conflated reasons: It made constraint set displays nicer, since we wouldn't render multiple constraints with obviously equivalent bounds. (Think T ≤ A & B and T ≤ B & A) But it was also useful for correctness, since prior to #21463 we were (trying to) add the full transitive closure to a constraint set's BDD, and normalization gave a useful reduction in the number of nodes in a typical BDD.

Now that we don't store the transitive closure explicitly, that second reason is no longer relevant. Our sequent map can store that full transitive closure much more efficiently than the expanded BDD would have. This helps fix some false positives on #20933, where we're seeing some (incorrect, need to be fixed, but ideally not blocking this effort) assignability failures between a type and its normalization.

Normalization is still useful for display purposes, and so we do normalize the upper/lower bounds before building up our display representation of a constraint set BDD.

@dcreager dcreager added the internal An internal refactor or improvement label Nov 18, 2025
@dcreager dcreager added the ty Multi-file analysis & type inference label Nov 18, 2025
@astral-sh-bot
Copy link

astral-sh-bot bot commented Nov 18, 2025

Diagnostic diff on typing conformance tests

No changes detected when running ty on typing conformance tests ✅

@astral-sh-bot
Copy link

astral-sh-bot bot commented Nov 18, 2025

mypy_primer results

Changes were detected when running on open source projects
scikit-build-core (https://github.com/scikit-build/scikit-build-core)
+ src/scikit_build_core/build/wheel.py:98:20: error[�]8;;https://ty.dev/rules#no-matching-overload�\no-matching-overload�]8;;�\] No overload of bound method `__init__` matches arguments
- Found 43 diagnostics
+ Found 44 diagnostics

No memory usage changes detected ✅

) {
// These might seem redundant with the intersection check below, since `a → b` means that
// `a ∧ b = a`. But we are not normalizing constraint bounds, and these clauses help us
// identity constraints that are identical besides e.g. ordering of union/intersection
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// identity constraints that are identical besides e.g. ordering of union/intersection
// identify constraints that are identical besides e.g. ordering of union/intersection

Comment on lines +2312 to +2317
if left_constraint.implies(db, right_constraint) {
self.add_single_implication(left_constraint, right_constraint);
}
if right_constraint.implies(db, left_constraint) {
self.add_single_implication(right_constraint, left_constraint);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The explanation above seems to imply that we could (should?) return early here? Because if a → b always implies a ∧ b = a, then the code below would otherwise add two additional a → b implications and one a → a implication, both of which seem unnecessary?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal An internal refactor or improvement ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants