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

Code before:
    }

    /// Return `true` if `self` conforms to the interface described by `protocol`.
    pub(super) fn satisfies_protocol(
        self,
        db: &'db dyn Db,
        protocol: ProtocolInstanceType<'db>,
        inferable: InferableTypeVars<'_, 'db>,
        relation: TypeRelation<'db>,
        relation_visitor: &HasRelationToVisitor<'db>,
        disjointness_visitor: &IsDisjointVisitor<'db>,
    ) -> ConstraintSet<'db> {
        let structurally_satisfied = if let Type::ProtocolInstance(self_protocol) = self {
            let self_as_nominal = self_protocol.to_nominal_instance();
            let other_as_nominal = protocol.to_nominal_instance();
            let nominal_match = match self_as_nominal.zip(other_as_nominal) {
                Some((self_as_nominal, other_as_nominal)) => self_as_nominal.has_relation_to_impl(
                    db,
                    other_as_nominal,
                    inferable,
                    relation,
                    relation_visitor,
                    disjointness_visitor,
                ),
                _ => ConstraintSet::from(false),
            };
            nominal_match.or(db, || {
                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(
                        db,
                        self,
                        inferable,
                        relation,
                        relation_visitor,
                        disjointness_visitor,
                    )
                })

Review comment (suggestion):
hmm, why are adding a nominal check up here when we already have this a few lines below? Should we delete the one lower down in this file? Or early-return here so we don't do the nominal check twice?

https://github.com/astral-sh/ruff/blob/e6dc572bb0848946051c7482fc4103070e309369/crates/ty_python_semantic/src/types/instance.rs#L180-L209

Code after:
    }

    /// Return `true` if `self` conforms to the interface described by `protocol`.
    pub(super) fn satisfies_protocol(
        self,
        db: &'db dyn Db,
        protocol: ProtocolInstanceType<'db>,
        inferable: InferableTypeVars<'_, 'db>,
        relation: TypeRelation<'db>,
        relation_visitor: &HasRelationToVisitor<'db>,
        disjointness_visitor: &IsDisjointVisitor<'db>,
    ) -> ConstraintSet<'db> {
        // `self` might satisfy the protocol nominally, if `protocol` is a class-based protocol and
        // `self` has the protocol class in its MRO. This is a much cheaper check than the
        // structural check we perform below, so we do it first to avoid the structural check when
        // we can.
        let mut result = ConstraintSet::from(false);
        if let Some(nominal_instance) = protocol.to_nominal_instance() {
            // if `self` and `other` are *both* protocols, we also need to treat `self` as if it
            // were a nominal type, or we won't consider a protocol `P` that explicitly inherits
            // from a protocol `Q` to be a subtype of `Q` to be a subtype of `Q` if it overrides
            // `Q`'s members in a Liskov-incompatible way.
            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;
            }
        }

        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,