## Summary This changeset adds support for precise type-inference and boundness-handling of definitions inside control-flow branches with statically-known conditions, i.e. test-expressions whose truthiness we can unambiguously infer as *always false* or *always true*. This branch also includes: - `sys.platform` support - statically-known branches handling for Boolean expressions and while loops - new `target-version` requirements in some Markdown tests which were now required due to the understanding of `sys.version_info` branches. closes #12700 closes #15034 ## Performance ### `tomllib`, -7%, needs to resolve one additional module (sys) | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `./red_knot_main --project /home/shark/tomllib` | 22.2 ± 1.3 | 19.1 | 25.6 | 1.00 | | `./red_knot_feature --project /home/shark/tomllib` | 23.8 ± 1.6 | 20.8 | 28.6 | 1.07 ± 0.09 | ### `black`, -6% | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | |:---|---:|---:|---:|---:| | `./red_knot_main --project /home/shark/black` | 129.3 ± 5.1 | 119.0 | 137.8 | 1.00 | | `./red_knot_feature --project /home/shark/black` | 136.5 ± 6.8 | 123.8 | 147.5 | 1.06 ± 0.07 | ## Test Plan - New Markdown tests for the main feature in `statically-known-branches.md` - New Markdown tests for `sys.platform` - Adapted tests for `EllipsisType`, `Never`, etc
53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
use ruff_db::files::File;
|
|
use ruff_python_ast::Singleton;
|
|
|
|
use crate::db::Db;
|
|
use crate::semantic_index::expression::Expression;
|
|
use crate::semantic_index::symbol::{FileScopeId, ScopeId};
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub(crate) struct Constraint<'db> {
|
|
pub(crate) node: ConstraintNode<'db>,
|
|
pub(crate) is_positive: bool,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
|
pub(crate) enum ConstraintNode<'db> {
|
|
Expression(Expression<'db>),
|
|
Pattern(PatternConstraint<'db>),
|
|
}
|
|
|
|
/// Pattern kinds for which we support type narrowing and/or static visibility analysis.
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub(crate) enum PatternConstraintKind<'db> {
|
|
Singleton(Singleton, Option<Expression<'db>>),
|
|
Value(Expression<'db>, Option<Expression<'db>>),
|
|
Unsupported,
|
|
}
|
|
|
|
#[salsa::tracked]
|
|
pub(crate) struct PatternConstraint<'db> {
|
|
#[id]
|
|
pub(crate) file: File,
|
|
|
|
#[id]
|
|
pub(crate) file_scope: FileScopeId,
|
|
|
|
#[no_eq]
|
|
#[return_ref]
|
|
pub(crate) subject: Expression<'db>,
|
|
|
|
#[no_eq]
|
|
#[return_ref]
|
|
pub(crate) kind: PatternConstraintKind<'db>,
|
|
|
|
#[no_eq]
|
|
count: countme::Count<PatternConstraint<'static>>,
|
|
}
|
|
|
|
impl<'db> PatternConstraint<'db> {
|
|
pub(crate) fn scope(self, db: &'db dyn Db) -> ScopeId<'db> {
|
|
self.file_scope(db).to_scope_id(db, self.file(db))
|
|
}
|
|
}
|