mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-23 16:51:58 +00:00
[ty] Eagerly evaluate TYPE_CHECKING
constraints (#19044)
## Summary Evaluate `TYPE_CHECKING` to `ALWAYS_TRUE` and `not TYPE_CHECKING` to `ALWAYS_FALSE` during semantic index building. This is a follow-up to https://github.com/astral-sh/ruff/pull/18998 and is in principle just a performance optimization. We see some (favorable) ecosystem changes because we can eliminate definitely-unreachable branches early now and retain narrowing constraints without solving https://github.com/astral-sh/ty/issues/690 first.
This commit is contained in:
parent
b8653a9d3a
commit
4016521bf6
1 changed files with 21 additions and 5 deletions
|
@ -542,15 +542,31 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_predicate(&mut self, predicate_node: &ast::Expr) -> PredicateOrLiteral<'db> {
|
fn build_predicate(&mut self, predicate_node: &ast::Expr) -> PredicateOrLiteral<'db> {
|
||||||
|
// Some commonly used test expressions are eagerly evaluated as `true`
|
||||||
|
// or `false` here for performance reasons. This list does not need to
|
||||||
|
// be exhaustive. More complex expressions will still evaluate to the
|
||||||
|
// correct value during type-checking.
|
||||||
|
fn resolve_to_literal(node: &ast::Expr) -> Option<bool> {
|
||||||
|
match node {
|
||||||
|
ast::Expr::BooleanLiteral(ast::ExprBooleanLiteral { value, .. }) => Some(*value),
|
||||||
|
ast::Expr::Name(ast::ExprName { id, .. }) if id == "TYPE_CHECKING" => Some(true),
|
||||||
|
ast::Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
|
op: ast::UnaryOp::Not,
|
||||||
|
operand,
|
||||||
|
..
|
||||||
|
}) => Some(!resolve_to_literal(operand)?),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let expression = self.add_standalone_expression(predicate_node);
|
let expression = self.add_standalone_expression(predicate_node);
|
||||||
|
|
||||||
if let Some(boolean_literal) = predicate_node.as_boolean_literal_expr() {
|
match resolve_to_literal(predicate_node) {
|
||||||
PredicateOrLiteral::Literal(boolean_literal.value)
|
Some(literal) => PredicateOrLiteral::Literal(literal),
|
||||||
} else {
|
None => PredicateOrLiteral::Predicate(Predicate {
|
||||||
PredicateOrLiteral::Predicate(Predicate {
|
|
||||||
node: PredicateNode::Expression(expression),
|
node: PredicateNode::Expression(expression),
|
||||||
is_positive: true,
|
is_positive: true,
|
||||||
})
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue