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

Code before:
        let use_id = self
            .body_scope(db)
            .node(db)
            .expect_function()
            .node(&module)
            .name
            .scoped_use_id(db, scope);

        let Place::Defined(Type::FunctionLiteral(previous_type), _, Definedness::AlwaysDefined) =
            place_from_bindings(db, use_def.bindings_at_use(use_id)).place
        else {
            return None;
        };

        let previous_literal = previous_type.literal(db);
        let previous_overload = previous_literal.last_definition(db);
        if !previous_overload.is_overload(db) {
            return None;
        }

        // These can both happen in edge cases involving not-yet-complete function definitions
        // (invalid syntax).
        if previous_overload.name(db) != self.name(db) {
            return None;
        }
        if previous_overload.body_scope(db).file(db) != self.file(db) {
            return None;
        }

        Some(previous_literal)
    }

    /// Typed internally-visible signature for this function.
    ///
    /// This represents the annotations on the function itself, unmodified by decorators and
    /// overloads.
    ///
    /// ## Warning
    ///
    /// This uses the semantic index to find the definition of the function. This means that if the
    /// calling query is not in the same file as this function is defined in, then this will create
    /// a cross-module dependency directly on the full AST which will lead to cache
    /// over-invalidation.
    pub(crate) fn signature(self, db: &'db dyn Db) -> Signature<'db> {
        let mut signature = self.raw_signature(db);

        let scope = self.body_scope(db);
        let module = parsed_module(db, self.file(db)).load(db);
        let function_node = scope.node(db).expect_function().node(&module);
        let index = semantic_index(db, scope.file(db));
        let file_scope_id = scope.file_scope_id(db);

Review comment (suggestion):
Maybe just consider comparing if `self.body_scope(db) == previous_overload.body_scope()` because I don't think we ever want to merge two overloads from different scopes

Code after:
    fn previous_overload(self, db: &'db dyn Db) -> Option<FunctionLiteral<'db>> {
        // The semantic model records a use for each function on the name node. This is used
        // here to get the previous function definition with the same name.
        let scope = self.definition(db).scope(db);
        let module = parsed_module(db, self.file(db)).load(db);
        let use_def = semantic_index(db, scope.file(db)).use_def_map(scope.file_scope_id(db));
        let use_id = self
            .body_scope(db)
            .node(db)
            .expect_function()
            .node(&module)
            .name
            .scoped_use_id(db, scope);

        let Place::Defined(DefinedPlace {
            ty: Type::FunctionLiteral(previous_type),
            definedness: Definedness::AlwaysDefined,
            ..
        }) = place_from_bindings(db, use_def.bindings_at_use(use_id)).place
        else {
            return None;
        };

        let previous_literal = previous_type.literal(db);
        let previous_overload = previous_literal.last_definition(db);
        if !previous_overload.is_overload(db) {
            return None;
        }

        // These can both happen in edge cases where a definition created with a `def`
        // statement shadows a non-`def` symbol with the same name.
        if previous_overload.name(db) != self.name(db) {
            return None;
        }
        if previous_overload.definition(db).scope(db) != scope {
            return None;
        }

        Some(previous_literal)
    }

    /// Typed internally-visible signature for this function.
    ///
    /// This represents the annotations on the function itself, unmodified by decorators and
    /// overloads.
    ///
    /// ## Warning
    ///
    /// This uses the semantic index to find the definition of the function. This means that if the
    /// calling query is not in the same file as this function is defined in, then this will create
    /// a cross-module dependency directly on the full AST which will lead to cache