astral-sh/ruff · error
every TDD constraint should have a source order
Error message
every TDD constraint should have a source order
What it means
`PathBounds::compute` walks the BDD's satisfying paths and sorts each path's constraints by their position in a registered source-order set (`source_orders: FxIndexSet<ConstraintId>`). The expect asserts every positive constraint encountered on a path has a registered source order; it fires when the path walker visits constraints the registration set does not contain.
Source
Thrown at crates/ty_python_semantic/src/types/constraints.rs:3744
impl Debug for NodeId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut f = f.debug_tuple("Node");
match self.node() {
// We use format_args instead of rendering the strings directly so that we don't get
// any quotes in the output: ScopedReachabilityConstraintId(AlwaysTrue) instead of
// ScopedReachabilityConstraintId("AlwaysTrue").
Node::AlwaysTrue => f.field(&format_args!("AlwaysTrue")),
Node::AlwaysFalse => f.field(&format_args!("AlwaysFalse")),
Node::Interior(_) => f.field(&self.0),
};
f.finish()
}
}
impl std::ops::Add<usize> for NodeId {
type Output = NodeId;
fn add(self, rhs: usize) -> Self::Output {
NodeId::from_usize(self.index() + rhs)
}
}
impl Idx for NodeId {
#[inline]
fn new(value: usize) -> Self {
Self::from_usize(value)
}
#[inline]
fn index(self) -> usize {
debug_assert!(!self.is_terminal());
self.0 as usize
}
}
View on GitHub (pinned to 15f3fe6b15)
Solutions
- Register every constraint in `source_orders` at the single point where it is added to the storage the walker will traverse.
- If registration can legitimately miss, return a deterministic fallback order (insert on miss) behind a debug assertion and investigate the miss.
- Add a regression mdtest with the constraint shape that panicked and run `cargo nextest run -p ty_python_semantic --test mdtest`.
- Report upstream with the fixture if stock ty panics.
Example fix
// before: constraint added to storage only let constraint = storage.add_constraint(db, c); // after: keep path ordering registration in lockstep let constraint = storage.add_constraint(db, c); source_orders.insert(constraint);
Defensive patterns
Strategy: try-catch
Try / catch
let bounds = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
PathBounds::compute(db, env, storage, node, inferable, source_order)
}))
.unwrap_or_else(|_| PathBounds::Unconstrained); // conservative fallback Prevention
- Contributors: register constraints in source_orders at insert time; the walker assumes total registration.
- Run the constraint-order wobble tests when touching ordering/determinism code.
- Users: capture the backtrace and constraint-heavy reproducer before reporting.
When it happens
Trigger: Computing per-path typevar bounds (assignability checks, bound narrowing) where a constraint on a path was never inserted into `self.source_orders` - e.g. constraints added during folding without registration, or a source-order set rebuilt/compacted differently than the path walker expects.
Common situations: Contributions to constraint ordering/determinism machinery (new constraint producers, compaction changes); surfaces in ordering-sensitive mdtests and the constraint-order wobble tests rather than normal checks.
Related errors
- non-terminal BDD should have source_order
- non-terminal constraint set should have a source_order
- typevar should be interned before ordering
- storage-free owned constraint sets must have terminal roots
- node should be non-terminal
AI-assisted analysis of astral-sh/ruff@15f3fe6b15 (2026-08-20).
Data as JSON: /api/errors/08fff8a7d5bea8d0.
Report an issue: GitHub.