Repository: astral-sh/ruff
File: crates/ty_python_semantic/src/types/signatures.rs (Rust)

Code before:
    let file = definition.file(db);
    let index = semantic_index(db, file);
    let file_scope = index.expression_scope_id(expression);
    let scope = file_scope.to_scope_id(db, file);
    if scope == definition.scope(db) {
        // expression is in the function definition scope, but always deferred
        infer_deferred_types(db, definition).expression_type(expression)
    } else {
        // expression is in the PEP-695 type params sub-scope
        infer_scope_types(db, scope).expression_type(expression)
    }
}

/// The signature of a single callable. If the callable is overloaded, there is a separate
/// [`Signature`] for each overload.
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
pub struct CallableSignature<'db> {
    /// The signatures of each overload of this callable. Will be empty if the type is not
    /// callable.
    pub(crate) overloads: SmallVec<[Signature<'db>; 1]>,
}

impl<'db> CallableSignature<'db> {
    pub(crate) fn single(signature: Signature<'db>) -> Self {
        Self {
            overloads: smallvec_inline![signature],
        }
    }

    pub(crate) fn bottom() -> Self {
        Self::single(Signature::bottom())
    }

    /// Creates a new `CallableSignature` from an iterator of [`Signature`]s. Returns a
    /// non-callable signature if the iterator is empty.
    pub(crate) fn from_overloads<I>(overloads: I) -> Self
    where
        I: IntoIterator<Item = Signature<'db>>,
    {
        Self {
            overloads: overloads.into_iter().collect(),
        }
    }

    pub(crate) fn iter(&self) -> std::slice::Iter<'_, Signature<'db>> {
        self.overloads.iter()
    }

    pub(crate) fn as_slice(&self) -> &[Signature<'db>] {
        &self.overloads
    }

Review comment (suggestion):
All of this stuff is moved over to `function.rs` to avoid this cyclic call to `infer_definition_types`

Code after:
    let file_scope = index.expression_scope_id(expression);
    let scope = file_scope.to_scope_id(db, file);
    if scope == definition.scope(db) {
        // expression is in the function definition scope, but always deferred
        infer_deferred_types(db, definition).expression_type(expression)
    } else {
        // expression is in the PEP-695 type params sub-scope
        infer_scope_types(db, scope).expression_type(expression)
    }
}

/// The signature of a single callable. If the callable is overloaded, there is a separate
/// [`Signature`] for each overload.
#[derive(Clone, Debug, PartialEq, Eq, Hash, salsa::Update, get_size2::GetSize)]
pub struct CallableSignature<'db> {
    /// The signatures of each overload of this callable. Will be empty if the type is not
    /// callable.
    pub(crate) overloads: SmallVec<[Signature<'db>; 1]>,
}

impl<'db> CallableSignature<'db> {
    pub(crate) fn single(signature: Signature<'db>) -> Self {
        Self {
            overloads: smallvec_inline![signature],
        }
    }

    pub(crate) fn bottom() -> Self {
        Self::single(Signature::bottom())
    }

    /// Creates a new `CallableSignature` from an iterator of [`Signature`]s. Returns a
    /// non-callable signature if the iterator is empty.
    pub(crate) fn from_overloads<I>(overloads: I) -> Self
    where
        I: IntoIterator<Item = Signature<'db>>,
    {
        Self {
            overloads: overloads.into_iter().collect(),
        }
    }

    pub(crate) fn iter(&self) -> std::slice::Iter<'_, Signature<'db>> {
        self.overloads.iter()
    }

    pub(crate) fn as_slice(&self) -> &[Signature<'db>] {
        &self.overloads
    }

    pub(crate) fn with_inherited_generic_context(