[ty] Cache `KnownClass::to_class_literal` (#22000)

This commit is contained in:
Micha Reiser 2025-12-16 13:04:12 +01:00 committed by GitHub
parent 01c0a3e960
commit b2b0ad38ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 34 additions and 17 deletions

View File

@ -5075,25 +5075,39 @@ impl KnownClass {
///
/// If the class cannot be found in typeshed, a debug-level log message will be emitted stating this.
pub(crate) fn try_to_class_literal(self, db: &dyn Db) -> Option<ClassLiteral<'_>> {
// a cache of the `KnownClass`es that we have already failed to lookup in typeshed
// (and therefore that we've already logged a warning for)
static MESSAGES: LazyLock<Mutex<FxHashSet<KnownClass>>> = LazyLock::new(Mutex::default);
#[salsa::interned(heap_size=ruff_memory_usage::heap_size)]
struct KnownClassArgument {
class: KnownClass,
}
self.try_to_class_literal_without_logging(db)
fn known_class_to_class_literal_initial<'db>(
_db: &'db dyn Db,
_id: salsa::Id,
_class: KnownClassArgument<'db>,
) -> Option<ClassLiteral<'db>> {
None
}
#[salsa::tracked(cycle_initial=known_class_to_class_literal_initial, heap_size=ruff_memory_usage::heap_size)]
fn known_class_to_class_literal<'db>(
db: &'db dyn Db,
class: KnownClassArgument<'db>,
) -> Option<ClassLiteral<'db>> {
let class = class.class(db);
class
.try_to_class_literal_without_logging(db)
.or_else(|lookup_error| {
if MESSAGES.lock().unwrap().insert(self) {
if matches!(
lookup_error,
KnownClassLookupError::ClassPossiblyUnbound { .. }
) {
tracing::info!("{}", lookup_error.display(db, self));
tracing::info!("{}", lookup_error.display(db, class));
} else {
tracing::info!(
"{}. Falling back to `Unknown` for the symbol instead.",
lookup_error.display(db, self)
lookup_error.display(db, class)
);
}
}
match lookup_error {
KnownClassLookupError::ClassPossiblyUnbound { class_literal, .. } => {
@ -5106,6 +5120,9 @@ impl KnownClass {
.ok()
}
known_class_to_class_literal(db, KnownClassArgument::new(db, self))
}
/// Lookup a [`KnownClass`] in typeshed and return a [`Type`] representing that class-literal.
///
/// If the class cannot be found in typeshed, a debug-level log message will be emitted stating this.