Skip to content

Commit 4bd0342

Browse files
authored
[ty] Inline cycle initial and recovery functions (#22814)
1 parent cb4fec2 commit 4bd0342

13 files changed

Lines changed: 124 additions & 427 deletions

File tree

crates/ty_python_semantic/src/dunder_all.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,9 @@ use crate::Db;
1111
use crate::semantic_index::{SemanticIndex, semantic_index};
1212
use crate::types::{Truthiness, Type, TypeContext, infer_expression_types};
1313

14-
fn dunder_all_names_cycle_initial(
15-
_db: &dyn Db,
16-
_id: salsa::Id,
17-
_file: File,
18-
) -> Option<FxHashSet<Name>> {
19-
None
20-
}
21-
2214
/// Returns a set of names in the `__all__` variable for `file`, [`None`] if it is not defined or
2315
/// if it contains invalid elements.
24-
#[salsa::tracked(returns(as_ref), cycle_initial=dunder_all_names_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
16+
#[salsa::tracked(returns(as_ref), cycle_initial=|_, _, _| None, heap_size=ruff_memory_usage::heap_size)]
2517
pub(crate) fn dunder_all_names(db: &dyn Db, file: File) -> Option<FxHashSet<Name>> {
2618
let _span = tracing::trace_span!("dunder_all_names", file=?file.path(db)).entered();
2719

crates/ty_python_semantic/src/place.rs

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -874,32 +874,13 @@ impl<'db> From<Place<'db>> for PlaceAndQualifiers<'db> {
874874
}
875875
}
876876

877-
fn place_cycle_initial<'db>(
878-
_db: &'db dyn Db,
879-
id: salsa::Id,
880-
_scope: ScopeId<'db>,
881-
_place_id: ScopedPlaceId,
882-
_requires_explicit_reexport: RequiresExplicitReExport,
883-
_considered_definitions: ConsideredDefinitions,
884-
) -> PlaceAndQualifiers<'db> {
885-
Place::bound(Type::divergent(id)).into()
886-
}
887-
888-
#[allow(clippy::too_many_arguments)]
889-
fn place_cycle_recover<'db>(
890-
db: &'db dyn Db,
891-
cycle: &salsa::Cycle,
892-
previous_place: &PlaceAndQualifiers<'db>,
893-
place: PlaceAndQualifiers<'db>,
894-
_scope: ScopeId<'db>,
895-
_place_id: ScopedPlaceId,
896-
_requires_explicit_reexport: RequiresExplicitReExport,
897-
_considered_definitions: ConsideredDefinitions,
898-
) -> PlaceAndQualifiers<'db> {
899-
place.cycle_normalized(db, *previous_place, cycle)
900-
}
901-
902-
#[salsa::tracked(cycle_fn=place_cycle_recover, cycle_initial=place_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
877+
#[salsa::tracked(
878+
cycle_initial=|_, id, _, _, _, _| Place::bound(Type::divergent(id)).into(),
879+
cycle_fn=|db, cycle, previous: &PlaceAndQualifiers<'db>, place: PlaceAndQualifiers<'db>, _, _, _, _| {
880+
place.cycle_normalized(db, *previous, cycle)
881+
},
882+
heap_size=ruff_memory_usage::heap_size
883+
)]
903884
pub(crate) fn place_by_id<'db>(
904885
db: &'db dyn Db,
905886
scope: ScopeId<'db>,
@@ -1756,7 +1737,7 @@ pub(crate) mod implicit_globals {
17561737
/// so the cost of hashing the names is likely to be more expensive than it's worth.
17571738
#[salsa::tracked(
17581739
returns(deref),
1759-
cycle_initial=module_type_symbols_initial,
1740+
cycle_initial=|_, _| smallvec::SmallVec::default(),
17601741
heap_size=ruff_memory_usage::heap_size
17611742
)]
17621743
fn module_type_symbols<'db>(db: &'db dyn Db) -> smallvec::SmallVec<[ast::name::Name; 8]> {
@@ -1788,13 +1769,6 @@ pub(crate) mod implicit_globals {
17881769
.collect()
17891770
}
17901771

1791-
fn module_type_symbols_initial(
1792-
_db: &dyn Db,
1793-
_id: salsa::Id,
1794-
) -> smallvec::SmallVec<[ast::name::Name; 8]> {
1795-
smallvec::SmallVec::default()
1796-
}
1797-
17981772
/// Returns an iterator over all implicit module global symbols and their types.
17991773
///
18001774
/// This is used for completions in the global scope of a module. It returns

crates/ty_python_semantic/src/semantic_index/re_exports.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ use ty_module_resolver::{ModuleName, resolve_module};
3131

3232
use crate::Db;
3333

34-
fn exports_cycle_initial(_db: &dyn Db, _id: salsa::Id, _file: File) -> Box<[Name]> {
35-
Box::default()
36-
}
37-
38-
#[salsa::tracked(returns(deref), cycle_initial=exports_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
34+
#[salsa::tracked(
35+
returns(deref),
36+
cycle_initial=|_, _, _| Box::default(),
37+
heap_size=ruff_memory_usage::heap_size)
38+
]
3939
pub(super) fn exported_names(db: &dyn Db, file: File) -> Box<[Name]> {
4040
let module = parsed_module(db, file).load(db);
4141
let mut finder = ExportFinder::new(db, file);

crates/ty_python_semantic/src/semantic_index/reachability_constraints.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,10 @@ fn type_excluded_by_previous_patterns<'db>(
375375
/// statement with N cases where each case references the subject (e.g., `self`), we would
376376
/// re-analyze each pattern O(N) times (once per reference), leading to O(N²) total work.
377377
/// With memoization, each pattern is analyzed exactly once.
378-
#[salsa::tracked(cycle_initial = analyze_pattern_predicate_cycle_initial, heap_size = get_size2::GetSize::get_heap_size)]
378+
#[salsa::tracked(
379+
cycle_initial = |_, _, _| Truthiness::Ambiguous,
380+
heap_size = get_size2::GetSize::get_heap_size
381+
)]
379382
fn analyze_pattern_predicate<'db>(db: &'db dyn Db, predicate: PatternPredicate<'db>) -> Truthiness {
380383
let subject_ty = infer_expression_type(db, predicate.subject(db), TypeContext::default());
381384

@@ -416,14 +419,6 @@ fn analyze_pattern_predicate<'db>(db: &'db dyn Db, predicate: PatternPredicate<'
416419
}
417420
}
418421

419-
fn analyze_pattern_predicate_cycle_initial<'db>(
420-
_db: &'db dyn Db,
421-
_id: salsa::Id,
422-
_predicate: PatternPredicate<'db>,
423-
) -> Truthiness {
424-
Truthiness::Ambiguous
425-
}
426-
427422
/// A collection of reachability constraints for a given scope.
428423
#[derive(Debug, PartialEq, Eq, salsa::Update, get_size2::GetSize)]
429424
pub(crate) struct ReachabilityConstraints {

crates/ty_python_semantic/src/types.rs

Lines changed: 37 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -364,59 +364,6 @@ impl Default for MemberLookupPolicy {
364364
}
365365
}
366366

367-
fn member_lookup_cycle_initial<'db>(
368-
_db: &'db dyn Db,
369-
id: salsa::Id,
370-
_self: Type<'db>,
371-
_name: Name,
372-
_policy: MemberLookupPolicy,
373-
) -> PlaceAndQualifiers<'db> {
374-
Place::bound(Type::divergent(id)).into()
375-
}
376-
377-
fn member_lookup_cycle_recover<'db>(
378-
db: &'db dyn Db,
379-
cycle: &salsa::Cycle,
380-
previous_member: &PlaceAndQualifiers<'db>,
381-
member: PlaceAndQualifiers<'db>,
382-
_self_type: Type<'db>,
383-
_name: Name,
384-
_policy: MemberLookupPolicy,
385-
) -> PlaceAndQualifiers<'db> {
386-
member.cycle_normalized(db, *previous_member, cycle)
387-
}
388-
389-
fn class_lookup_cycle_initial<'db>(
390-
_db: &'db dyn Db,
391-
id: salsa::Id,
392-
_self: Type<'db>,
393-
_name: Name,
394-
_policy: MemberLookupPolicy,
395-
) -> PlaceAndQualifiers<'db> {
396-
Place::bound(Type::divergent(id)).into()
397-
}
398-
399-
fn class_lookup_cycle_recover<'db>(
400-
db: &'db dyn Db,
401-
cycle: &salsa::Cycle,
402-
previous_member: &PlaceAndQualifiers<'db>,
403-
member: PlaceAndQualifiers<'db>,
404-
_self_type: Type<'db>,
405-
_name: Name,
406-
_policy: MemberLookupPolicy,
407-
) -> PlaceAndQualifiers<'db> {
408-
member.cycle_normalized(db, *previous_member, cycle)
409-
}
410-
411-
fn variance_cycle_initial<'db, T>(
412-
_db: &'db dyn Db,
413-
_id: salsa::Id,
414-
_self: T,
415-
_typevar: BoundTypeVarInstance<'db>,
416-
) -> TypeVarVariance {
417-
TypeVarVariance::Bivariant
418-
}
419-
420367
/// Meta data for `Type::Todo`, which represents a known limitation in ty.
421368
#[cfg(debug_assertions)]
422369
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, get_size2::GetSize)]
@@ -2470,7 +2417,13 @@ impl<'db> Type<'db> {
24702417
self.class_member_with_policy(db, name, MemberLookupPolicy::default())
24712418
}
24722419

2473-
#[salsa::tracked(cycle_fn=class_lookup_cycle_recover, cycle_initial=class_lookup_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
2420+
#[salsa::tracked(
2421+
cycle_initial=|_, id, _, _, _| Place::bound(Type::divergent(id)).into(),
2422+
cycle_fn=|db, cycle, previous: &PlaceAndQualifiers<'db>, member: PlaceAndQualifiers<'db>, _, _, _| {
2423+
member.cycle_normalized(db, *previous, cycle)
2424+
},
2425+
heap_size=ruff_memory_usage::heap_size
2426+
)]
24742427
fn class_member_with_policy(
24752428
self,
24762429
db: &'db dyn Db,
@@ -3020,7 +2973,13 @@ impl<'db> Type<'db> {
30202973

30212974
/// Similar to [`Type::member`], but allows the caller to specify what policy should be used
30222975
/// when looking up attributes. See [`MemberLookupPolicy`] for more information.
3023-
#[salsa::tracked(cycle_fn=member_lookup_cycle_recover, cycle_initial=member_lookup_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
2976+
#[salsa::tracked(
2977+
cycle_initial=|_, id, _, _, _| Place::bound(Type::divergent(id)).into(),
2978+
cycle_fn=|db, cycle, previous: &PlaceAndQualifiers<'db>, member: PlaceAndQualifiers<'db>, _, _, _| {
2979+
member.cycle_normalized(db, *previous, cycle)
2980+
},
2981+
heap_size=ruff_memory_usage::heap_size
2982+
)]
30242983
pub(crate) fn member_lookup_with_policy(
30252984
self,
30262985
db: &'db dyn Db,
@@ -5919,7 +5878,13 @@ impl<'db> Type<'db> {
59195878
/// Note that this does not specialize generic classes, functions, or type aliases! That is a
59205879
/// different operation that is performed explicitly (via a subscript operation), or implicitly
59215880
/// via a call to the generic object.
5922-
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size, cycle_fn=apply_specialization_cycle_recover, cycle_initial=apply_specialization_cycle_initial)]
5881+
#[salsa::tracked(
5882+
cycle_initial=|_, id, _, _| Type::divergent(id),
5883+
cycle_fn=|db, cycle, previous: &Type<'db>, value: Type<'db>, _, _| {
5884+
value.cycle_normalized(db, *previous, cycle)
5885+
},
5886+
heap_size=ruff_memory_usage::heap_size
5887+
)]
59235888
pub(crate) fn apply_specialization(
59245889
self,
59255890
db: &'db dyn Db,
@@ -6517,7 +6482,13 @@ impl<'db> Type<'db> {
65176482
}
65186483

65196484
#[allow(clippy::used_underscore_binding)]
6520-
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size, cycle_fn=expand_eagerly_cycle_recover, cycle_initial=expand_eagerly_cycle_initial)]
6485+
#[salsa::tracked(
6486+
cycle_initial=|_, id, _, ()| Type::divergent(id),
6487+
cycle_fn=|db, cycle, previous: &Type<'db>, value: Type<'db>, _, ()| {
6488+
value.cycle_normalized(db, *previous, cycle)
6489+
},
6490+
heap_size=ruff_memory_usage::heap_size
6491+
)]
65216492
fn expand_eagerly_(self, db: &'db dyn Db, _unit: ()) -> Type<'db> {
65226493
self.apply_type_mapping(db, &TypeMapping::EagerExpansion, TypeContext::default())
65236494
}
@@ -6850,46 +6821,6 @@ impl<'db> VarianceInferable<'db> for Type<'db> {
68506821
}
68516822
}
68526823

6853-
fn apply_specialization_cycle_recover<'db>(
6854-
db: &'db dyn Db,
6855-
cycle: &salsa::Cycle,
6856-
previous_value: &Type<'db>,
6857-
value: Type<'db>,
6858-
_self: Type<'db>,
6859-
_specialization: Specialization<'db>,
6860-
) -> Type<'db> {
6861-
value.cycle_normalized(db, *previous_value, cycle)
6862-
}
6863-
6864-
fn apply_specialization_cycle_initial<'db>(
6865-
_db: &'db dyn Db,
6866-
id: salsa::Id,
6867-
_self: Type<'db>,
6868-
_specialization: Specialization<'db>,
6869-
) -> Type<'db> {
6870-
Type::divergent(id)
6871-
}
6872-
6873-
fn expand_eagerly_cycle_initial<'db>(
6874-
_db: &'db dyn Db,
6875-
id: salsa::Id,
6876-
_self: Type<'db>,
6877-
_unit: (),
6878-
) -> Type<'db> {
6879-
Type::divergent(id)
6880-
}
6881-
6882-
fn expand_eagerly_cycle_recover<'db>(
6883-
db: &'db dyn Db,
6884-
cycle: &salsa::Cycle,
6885-
previous_value: &Type<'db>,
6886-
value: Type<'db>,
6887-
_self: Type<'db>,
6888-
_unit: (),
6889-
) -> Type<'db> {
6890-
value.cycle_normalized(db, *previous_value, cycle)
6891-
}
6892-
68936824
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, get_size2::GetSize)]
68946825
pub enum PromoteLiteralsMode {
68956826
On,
@@ -8190,7 +8121,7 @@ impl<'db> TypeVarInstance<'db> {
81908121
Some(TypeVarBoundOrConstraints::Constraints(constraints))
81918122
}
81928123

8193-
#[salsa::tracked(cycle_fn=lazy_default_cycle_recover, cycle_initial=lazy_default_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
8124+
#[salsa::tracked(cycle_initial=|_, id, _| Some(Type::divergent(id)), cycle_fn=lazy_default_cycle_recover, heap_size=ruff_memory_usage::heap_size)]
81948125
fn lazy_default(self, db: &'db dyn Db) -> Option<Type<'db>> {
81958126
fn convert_type_to_paramspec_value<'db>(db: &'db dyn Db, ty: Type<'db>) -> Type<'db> {
81968127
let parameters = match ty {
@@ -8328,15 +8259,6 @@ fn lazy_default_cycle_recover<'db>(
83288259
}
83298260
}
83308261

8331-
#[allow(clippy::unnecessary_wraps)]
8332-
fn lazy_default_cycle_initial<'db>(
8333-
_db: &'db dyn Db,
8334-
id: salsa::Id,
8335-
_self: TypeVarInstance<'db>,
8336-
) -> Option<Type<'db>> {
8337-
Some(Type::divergent(id))
8338-
}
8339-
83408262
/// Where a type variable is bound and usable.
83418263
#[derive(
83428264
Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, salsa::Update, get_size2::GetSize,
@@ -11541,7 +11463,13 @@ impl<'db> PEP695TypeAliasType<'db> {
1154111463

1154211464
/// The RHS type of a PEP-695 style type alias with *no* specialization applied.
1154311465
/// Returns `Divergent` if the type alias is defined cyclically.
11544-
#[salsa::tracked(cycle_fn=value_type_cycle_recover, cycle_initial=value_type_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
11466+
#[salsa::tracked(
11467+
cycle_initial=|_, id, _| Type::divergent(id),
11468+
cycle_fn=|db, cycle, previous: &Type<'db>, value: Type<'db>, _| {
11469+
value.cycle_normalized(db, *previous, cycle)
11470+
},
11471+
heap_size=ruff_memory_usage::heap_size
11472+
)]
1154511473
fn raw_value_type(self, db: &'db dyn Db) -> Type<'db> {
1154611474
let scope = self.rhs_scope(db);
1154711475
let module = parsed_module(db, scope.file(db)).load(db);
@@ -11591,7 +11519,7 @@ impl<'db> PEP695TypeAliasType<'db> {
1159111519
self.specialization(db).is_some()
1159211520
}
1159311521

11594-
#[salsa::tracked(cycle_initial=generic_context_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
11522+
#[salsa::tracked(cycle_initial=|_, _, _| None, heap_size=ruff_memory_usage::heap_size)]
1159511523
pub(crate) fn generic_context(self, db: &'db dyn Db) -> Option<GenericContext<'db>> {
1159611524
let scope = self.rhs_scope(db);
1159711525
let file = scope.file(db);
@@ -11614,32 +11542,6 @@ impl<'db> PEP695TypeAliasType<'db> {
1161411542
}
1161511543
}
1161611544

11617-
fn generic_context_cycle_initial<'db>(
11618-
_db: &'db dyn Db,
11619-
_id: salsa::Id,
11620-
_self: PEP695TypeAliasType<'db>,
11621-
) -> Option<GenericContext<'db>> {
11622-
None
11623-
}
11624-
11625-
fn value_type_cycle_initial<'db>(
11626-
_db: &'db dyn Db,
11627-
id: salsa::Id,
11628-
_self: PEP695TypeAliasType<'db>,
11629-
) -> Type<'db> {
11630-
Type::divergent(id)
11631-
}
11632-
11633-
fn value_type_cycle_recover<'db>(
11634-
db: &'db dyn Db,
11635-
cycle: &salsa::Cycle,
11636-
previous_value: &Type<'db>,
11637-
value: Type<'db>,
11638-
_self: PEP695TypeAliasType<'db>,
11639-
) -> Type<'db> {
11640-
value.cycle_normalized(db, *previous_value, cycle)
11641-
}
11642-
1164311545
/// A PEP 695 `types.TypeAliasType` created by manually calling the constructor.
1164411546
///
1164511547
/// # Ordering

0 commit comments

Comments
 (0)