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

Code before:
            let type_to_test = self
                .as_protocol_instance()
                .and_then(ProtocolInstanceType::to_nominal_instance)
                .map(Type::NominalInstance)
                .unwrap_or(self);
            let nominally_satisfied = type_to_test.has_relation_to_impl(
                db,
                Type::NominalInstance(nominal_instance),
                inferable,
                relation,
                relation_visitor,
                disjointness_visitor,
            );
            if result
                .union(db, nominally_satisfied)
                .is_always_satisfied(db)
            {
                return result;
            }
        }

        // `Generator` special case: Prior to 3.13, the `_ReturnT_co` type didn't appear in any
        // methods (except `__iter__`, but that returns the self type recursively, which gets
        // normalized to `Any`). We don't want generators with different return types to be
        // assignable to each other. In this case we use the result of the nominal check above.
        if Program::get(db).python_version(db) < PythonVersion::PY313
            && let Some(self_protocol) = self.as_protocol_instance()
            && let Protocol::FromClass(self_class) = self_protocol.inner
            && let Protocol::FromClass(proto_class) = protocol.inner
            && self_class.known(db) == Some(KnownClass::Generator)
            && proto_class.known(db) == Some(KnownClass::Generator)
        {
            return result;
        }

        let structurally_satisfied = if let Type::ProtocolInstance(self_protocol) = self {
            self_protocol.interface(db).has_relation_to_impl(
                db,
                protocol.interface(db),
                inferable,
                relation,
                relation_visitor,
                disjointness_visitor,
            )
        } else {
            protocol
                .inner
                .interface(db)
                .members(db)
                .when_all(db, |member| {
                    member.is_satisfied_by(

Review comment (bug):
I seem to remember that these `Program::get(db).python_version(db)` are somewhat expensive? If so, should we consider testing the Python version further down in this `&&` chain?

I could easily be wrong here with that assumption though.

Code after:
            let type_to_test = self
                .as_protocol_instance()
                .and_then(ProtocolInstanceType::to_nominal_instance)
                .map(Type::NominalInstance)
                .unwrap_or(self);
            let nominally_satisfied = type_to_test.has_relation_to_impl(
                db,
                Type::NominalInstance(nominal_instance),
                inferable,
                relation,
                relation_visitor,
                disjointness_visitor,
            );
            if result
                .union(db, nominally_satisfied)
                .is_always_satisfied(db)
            {
                return result;
            }
        }

        // `Generator` special case: Prior to 3.13, the `_ReturnT_co` type didn't appear in any
        // methods (except `__iter__`, but that returns the self type recursively, which gets
        // normalized to `Any`). We don't want generators with different return types to be
        // assignable to each other. In this case we use the result of the nominal check above.
        if let Some(self_protocol) = self.as_protocol_instance()
            && let Protocol::FromClass(self_class) = self_protocol.inner
            && let Protocol::FromClass(proto_class) = protocol.inner
            && self_class.known(db) == Some(KnownClass::Generator)
            && proto_class.known(db) == Some(KnownClass::Generator)
            && Program::get(db).python_version(db) < PythonVersion::PY313
        {
            return result;
        }

        let structurally_satisfied = if let Type::ProtocolInstance(self_protocol) = self {
            self_protocol.interface(db).has_relation_to_impl(
                db,
                protocol.interface(db),
                inferable,
                relation,
                relation_visitor,
                disjointness_visitor,
            )
        } else {
            protocol
                .inner
                .interface(db)
                .members(db)
                .when_all(db, |member| {
                    member.is_satisfied_by(