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

Code before:
            generic_context: self.generic_context,
            definition: self.definition,
            parameters,
            return_ty,
        }
    }

    fn inferable_typevars(&self, db: &'db dyn Db) -> InferableTypeVars<'db, 'db> {
        match self.generic_context {
            Some(generic_context) => generic_context.inferable_typevars(db),
            None => InferableTypeVars::None,
        }
    }

    /// Return `true` if `self` has exactly the same set of possible static materializations as
    /// `other` (if `self` represents the same set of possible sets of possible runtime objects as
    /// `other`).
    pub(crate) fn is_equivalent_to_impl(
        &self,
        db: &'db dyn Db,
        other: &Signature<'db>,
        inferable: InferableTypeVars<'_, 'db>,
        visitor: &IsEquivalentVisitor<'db>,
    ) -> ConstraintSet<'db> {
        let mut result = ConstraintSet::from(true);
        let mut check_types = |self_type: Option<Type<'db>>, other_type: Option<Type<'db>>| {
            let self_type = self_type.unwrap_or(Type::unknown());
            let other_type = other_type.unwrap_or(Type::unknown());
            !result
                .intersect(
                    db,
                    self_type.is_equivalent_to_impl(db, other_type, inferable, visitor),
                )
                .is_never_satisfied(db)
        };

        if self.parameters.is_gradual() != other.parameters.is_gradual() {
            return ConstraintSet::from(false);
        }

        if self.parameters.len() != other.parameters.len() {
            return ConstraintSet::from(false);
        }

        if !check_types(self.return_ty, other.return_ty) {
            return result;
        }

        for (self_parameter, other_parameter) in self.parameters.iter().zip(&other.parameters) {
            match (self_parameter.kind(), other_parameter.kind()) {
                (

Review comment (bug):
Was this just wrong? Or unnecessary

I don't see any new/changed tests above regarding equivalence of callables, but apparently removing this doesn't break any tests?

Code after:
            generic_context: self.generic_context,
            definition: self.definition,
            parameters,
            return_ty,
        }
    }

    fn inferable_typevars(&self, db: &'db dyn Db) -> InferableTypeVars<'db, 'db> {
        match self.generic_context {
            Some(generic_context) => generic_context.inferable_typevars(db),
            None => InferableTypeVars::None,
        }
    }

    /// Return `true` if `self` has exactly the same set of possible static materializations as
    /// `other` (if `self` represents the same set of possible sets of possible runtime objects as
    /// `other`).
    pub(crate) fn is_equivalent_to_impl(
        &self,
        db: &'db dyn Db,
        other: &Signature<'db>,
        inferable: InferableTypeVars<'_, 'db>,
        visitor: &IsEquivalentVisitor<'db>,
    ) -> ConstraintSet<'db> {
        // If either signature is generic, their typevars should also be considered inferable when
        // checking whether the signatures are equivalent, since we only need to find one
        // specialization that causes the check to succeed.
        //
        // TODO: We should alpha-rename these typevars, too, to correctly handle when a generic
        // callable refers to typevars from within the context that defines them. This primarily
        // comes up when referring to a generic function recursively from within its body:
        //
        //     def identity[T](t: T) -> T:
        //         # Here, TypeOf[identity2] is a generic callable that should consider T to be
        //         # inferable, even though other uses of T in the function body are non-inferable.
        //         return t
        let self_inferable = self.inferable_typevars(db);
        let other_inferable = other.inferable_typevars(db);
        let inferable = inferable.merge(&self_inferable);
        let inferable = inferable.merge(&other_inferable);

        // `inner` will create a constraint set that references these newly inferable typevars.
        let when = self.is_equivalent_to_inner(db, other, inferable, visitor);

        // But the caller does not need to consider those extra typevars. Whatever constraint set
        // we produce, we reduce it back down to the inferable set that the caller asked about.
        // If we introduced new inferable typevars, those will be existentially quantified away
        // before returning.
        when.reduce_inferable(db, self_inferable.iter().chain(other_inferable.iter()))
    }