Skip to content

Commit 82796df

Browse files
authored
[ty] add cycle handling to BoundMethodType::into_callable_type() (#20369)
## Summary This looks like it should fix the errors that we've been seeing in sympy in recent mypy-primer runs. ## Test Plan I wasn't able to reproduce the sympy failures locally; it looks like there is probably a dependency on the order in which files are checked. So I don't have a minimal reproducible example, and wasn't able to add a test :/ Obviously I would be happier if we could commit a regression test here, but since the change is straightforward and clearly desirable, I'm not sure how many hours it's worth trying to track it down. Mypy-primer is still failing in CI on this PR, because it fails on the "old" ty commit already (i.e. on main). But it passes [on a no-op PR stacked on top of this](#20370), which strongly suggests this PR fixes the problem.
1 parent dfec946 commit 82796df

File tree

3 files changed

+25
-5
lines changed

3 files changed

+25
-5
lines changed

crates/ty_python_semantic/src/types.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8938,6 +8938,23 @@ fn walk_bound_method_type<'db, V: visitor::TypeVisitor<'db> + ?Sized>(
89388938
visitor.visit_type(db, method.self_instance(db));
89398939
}
89408940

8941+
#[allow(clippy::trivially_copy_pass_by_ref)]
8942+
fn into_callable_type_cycle_recover<'db>(
8943+
_db: &'db dyn Db,
8944+
_value: &CallableType<'db>,
8945+
_count: u32,
8946+
_self: BoundMethodType<'db>,
8947+
) -> salsa::CycleRecoveryAction<CallableType<'db>> {
8948+
salsa::CycleRecoveryAction::Iterate
8949+
}
8950+
8951+
fn into_callable_type_cycle_initial<'db>(
8952+
db: &'db dyn Db,
8953+
_self: BoundMethodType<'db>,
8954+
) -> CallableType<'db> {
8955+
CallableType::bottom(db)
8956+
}
8957+
89418958
#[salsa::tracked]
89428959
impl<'db> BoundMethodType<'db> {
89438960
/// Returns the type that replaces any `typing.Self` annotations in the bound method signature.
@@ -8951,7 +8968,7 @@ impl<'db> BoundMethodType<'db> {
89518968
self_instance
89528969
}
89538970

8954-
#[salsa::tracked(heap_size=ruff_memory_usage::heap_size)]
8971+
#[salsa::tracked(cycle_fn=into_callable_type_cycle_recover, cycle_initial=into_callable_type_cycle_initial, heap_size=ruff_memory_usage::heap_size)]
89558972
pub(crate) fn into_callable_type(self, db: &'db dyn Db) -> CallableType<'db> {
89568973
let function = self.function(db);
89578974
let self_instance = self.typing_self_type(db);
@@ -9089,9 +9106,8 @@ impl<'db> CallableType<'db> {
90899106
///
90909107
/// Specifically, this represents a callable type with a single signature:
90919108
/// `(*args: object, **kwargs: object) -> Never`.
9092-
#[cfg(test)]
9093-
pub(crate) fn bottom(db: &'db dyn Db) -> Type<'db> {
9094-
Self::single(db, Signature::bottom())
9109+
pub(crate) fn bottom(db: &'db dyn Db) -> CallableType<'db> {
9110+
Self::new(db, CallableSignature::bottom(), false)
90959111
}
90969112

90979113
/// Return a "normalized" version of this `Callable` type.

crates/ty_python_semantic/src/types/property_tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ mod stable {
158158
type_property_test!(
159159
bottom_callable_is_subtype_of_all_callable, db,
160160
forall types t. t.is_callable_type()
161-
=> CallableType::bottom(db).is_subtype_of(db, t)
161+
=> Type::Callable(CallableType::bottom(db)).is_subtype_of(db, t)
162162
);
163163

164164
// `T` can be assigned to itself.

crates/ty_python_semantic/src/types/signatures.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ impl<'db> CallableSignature<'db> {
4343
}
4444
}
4545

46+
pub(crate) fn bottom() -> Self {
47+
Self::single(Signature::bottom())
48+
}
49+
4650
/// Creates a new `CallableSignature` from an iterator of [`Signature`]s. Returns a
4751
/// non-callable signature if the iterator is empty.
4852
pub(crate) fn from_overloads<I>(overloads: I) -> Self

0 commit comments

Comments
 (0)