[red-knot] Reduce Salsa lookups in `Type::find_name_in_mro` (#16582)

## Summary

Theoretically this should be slightly more performant, since the
`class.is_known()` calls each do a separate Salsa lookup, which we can
avoid if we do a single `match` on the value of `class.known()`. It also
ends up being two lines less code overall!

## Test Plan

`cargo test -p red_knot_python_semantic`
This commit is contained in:
Alex Waygood 2025-03-10 06:55:22 +00:00 committed by GitHub
parent c970b794d0
commit b6c7ba4f8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 28 additions and 30 deletions

View File

@ -1457,15 +1457,13 @@ impl<'db> Type<'db> {
Type::Dynamic(_) | Type::Never => Some(Symbol::bound(self).into()),
Type::ClassLiteral(ClassLiteralType { class })
if class.is_known(db, KnownClass::FunctionType) && name == "__get__" =>
{
Some(Symbol::bound(Type::Callable(CallableType::WrapperDescriptorDunderGet)).into())
}
Type::ClassLiteral(ClassLiteralType { class })
if class.is_known(db, KnownClass::FunctionType)
&& matches!(name, "__set__" | "__delete__") =>
{
Type::ClassLiteral(class_literal @ ClassLiteralType { class }) => {
match (class.known(db), name) {
(Some(KnownClass::FunctionType), "__get__") => Some(
Symbol::bound(Type::Callable(CallableType::WrapperDescriptorDunderGet))
.into(),
),
(Some(KnownClass::FunctionType), "__set__" | "__delete__") => {
// Hard code this knowledge, as we look up `__set__` and `__delete__` on `FunctionType` often.
Some(Symbol::Unbound.into())
}
@ -1477,9 +1475,7 @@ impl<'db> Type<'db> {
// because we make extensive use of these types in our test suite. Note that some
// builtin types are not included here, since they do not have generic bases and
// are correctly handled by the `find_name_in_mro` method.
Type::ClassLiteral(class)
if matches!(
class.class.known(db),
(
Some(
KnownClass::Int
| KnownClass::Str
@ -1487,12 +1483,13 @@ impl<'db> Type<'db> {
| KnownClass::Tuple
| KnownClass::Slice
| KnownClass::Range,
)
) && matches!(name, "__get__" | "__set__" | "__delete__") =>
{
Some(Symbol::Unbound.into())
),
"__get__" | "__set__" | "__delete__",
) => Some(Symbol::Unbound.into()),
_ => Some(class_literal.class_member(db, name)),
}
}
Type::ClassLiteral(class_literal) => Some(class_literal.class_member(db, name)),
Type::SubclassOf(subclass_of)
if name == "__get__"
@ -1523,6 +1520,7 @@ impl<'db> Type<'db> {
.to_class_literal(db)
.find_name_in_mro(db, name)
}
Type::FunctionLiteral(_)
| Type::Callable(_)
| Type::ModuleLiteral(_)