[red-knot] Add cycle handling to narrow constraints queries (#17209)

## Summary

This PR fixes the cycle issue that was causing problems in the `support
super` PR.

### Affected queries
- `all_narrowing_constraints_for_expression`
- `all_negative_narrowing_constraints_for_expression`


--

Additionally, `bidict` and `werkzeug` have been added to the
project-selection list in `mypy_primer`.
This PR also addresses the panics that occurred while analyzing those
packages:

- `bidict`: panic triggered by
`all_narrowing_constraints_for_expression`
- `werkzeug`: panic triggered by
`all_negative_narrowing_constraints_for_expression`

I think the mypy-primer results for this PR can serve as sufficient test
:)
This commit is contained in:
cake-monotone 2025-04-05 14:26:20 +09:00 committed by GitHub
parent 1a6a10b30f
commit 7e6d3838bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 3 deletions

View File

@ -68,7 +68,7 @@ jobs:
--type-checker knot \
--old base_commit \
--new "$GITHUB_SHA" \
--project-selector '/(mypy_primer|black|pyp|git-revise|zipp|arrow|isort|itsdangerous|rich|packaging|pybind11|pyinstrument|typeshed-stats|scrapy)$' \
--project-selector '/(mypy_primer|black|pyp|git-revise|zipp|arrow|isort|itsdangerous|rich|packaging|pybind11|pyinstrument|typeshed-stats|scrapy|werkzeug|bidict)$' \
--output concise \
--debug > mypy_primer.diff || [ $? -eq 1 ]

View File

@ -69,7 +69,11 @@ fn all_narrowing_constraints_for_pattern<'db>(
}
#[allow(clippy::ref_option)]
#[salsa::tracked(return_ref)]
#[salsa::tracked(
return_ref,
cycle_fn=constraints_for_expression_cycle_recover,
cycle_initial=constraints_for_expression_cycle_initial,
)]
fn all_narrowing_constraints_for_expression<'db>(
db: &'db dyn Db,
expression: Expression<'db>,
@ -78,7 +82,11 @@ fn all_narrowing_constraints_for_expression<'db>(
}
#[allow(clippy::ref_option)]
#[salsa::tracked(return_ref)]
#[salsa::tracked(
return_ref,
cycle_fn=negative_constraints_for_expression_cycle_recover,
cycle_initial=negative_constraints_for_expression_cycle_initial,
)]
fn all_negative_narrowing_constraints_for_expression<'db>(
db: &'db dyn Db,
expression: Expression<'db>,
@ -86,6 +94,40 @@ fn all_negative_narrowing_constraints_for_expression<'db>(
NarrowingConstraintsBuilder::new(db, PredicateNode::Expression(expression), false).finish()
}
#[allow(clippy::ref_option)]
fn constraints_for_expression_cycle_recover<'db>(
_db: &'db dyn Db,
_value: &Option<NarrowingConstraints<'db>>,
_count: u32,
_expression: Expression<'db>,
) -> salsa::CycleRecoveryAction<Option<NarrowingConstraints<'db>>> {
salsa::CycleRecoveryAction::Iterate
}
fn constraints_for_expression_cycle_initial<'db>(
_db: &'db dyn Db,
_expression: Expression<'db>,
) -> Option<NarrowingConstraints<'db>> {
None
}
#[allow(clippy::ref_option)]
fn negative_constraints_for_expression_cycle_recover<'db>(
_db: &'db dyn Db,
_value: &Option<NarrowingConstraints<'db>>,
_count: u32,
_expression: Expression<'db>,
) -> salsa::CycleRecoveryAction<Option<NarrowingConstraints<'db>>> {
salsa::CycleRecoveryAction::Iterate
}
fn negative_constraints_for_expression_cycle_initial<'db>(
_db: &'db dyn Db,
_expression: Expression<'db>,
) -> Option<NarrowingConstraints<'db>> {
None
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum KnownConstraintFunction {
/// `builtins.isinstance`