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

Code before:
                    .known(db)
                    .is_some_and(KnownClass::is_fallback_class)
            {
                let scope_id = definition.scope(db);
                let typevar_binding_context = Some(definition);
                let index = semantic_index(db, scope_id.file(db));
                let class = nearest_enclosing_class(db, index, scope_id).unwrap();

                let typing_self = typing_self(db, scope_id, typevar_binding_context, class).expect(
                    "We should always find the surrounding class \
                     for an implicit self: Self annotation",
                );

                if self.is_classmethod(db) {
                    Some(SubclassOfType::from(
                        db,
                        SubclassOfInner::TypeVar(typing_self),
                    ))
                } else {
                    Some(Type::TypeVar(typing_self))
                }
            } else {
                // For methods of non-generic classes that are not otherwise generic (e.g. return `Self` or
                // have additional type parameters), the implicit `Self` type of the `self`, or the implicit
                // `type[Self]` type of the `cls` parameter, would be the only type variable, so we can just
                // use the class directly.
                if self.is_classmethod(db) {
                    Some(SubclassOfType::from(
                        db,
                        SubclassOfInner::Class(ClassType::NonGeneric(class_literal)),
                    ))
                } else {
                    Some(class_literal.to_non_generic_instance(db))
                }
            }
        });

        raw_signature
    }

    pub(crate) fn parameter_span(
        self,
        db: &'db dyn Db,
        parameter_index: Option<usize>,
    ) -> Option<(Span, Span)> {
        let function_scope = self.body_scope(db);
        let span = Span::from(function_scope.file(db));
        let node = function_scope.node(db);
        let module = parsed_module(db, self.file(db)).load(db);
        let func_def = node.as_function()?.node(&module);
        let range = parameter_index

Review comment (suggestion):
It doesn't seem like this matches what we check above, which is actually just that an explicit `Self` is in the type parameters -- we don't seem to care whether there are other type parameters. (That logic seems fine to me, it just doesn't match the text here, or the `method_may_be_generic` variable name.)

Code after:
            // Normally we implicitly annotate `self` or `cls` with `Self` or `type[Self]`, and
            // create a `Self` typevar that we then have to solve for whenever this method is
            // called. As an optimization, we can skip creating that typevar in certain situations:
            //
            //   - The method cannot use explicit `Self` in any other parameter annotations,
            //     or in its return type. If it does, then we really do need specialization
            //     inference at each call site to see which specific instance type should be
            //     used in those other parameters / return type.
            //
            //   - The class cannot be generic. If it is, then we might need an actual `Self`
            //     typevar to help carry through constraints that relate the instance type to
            //     other typevars in the method signature.
            //
            //   - The class cannot be a "fallback class". A fallback class is used like a mixin,
            //     and so we need specialization inference to determine the "real" class that the
            //     fallback is augmenting. (See KnownClass::is_fallback_class for more details.)
            if method_has_explicit_self || class_is_generic || class_is_fallback {
                let scope_id = definition.scope(db);
                let typevar_binding_context = Some(definition);
                let index = semantic_index(db, scope_id.file(db));
                let class = nearest_enclosing_class(db, index, scope_id).unwrap();

                let typing_self = typing_self(db, scope_id, typevar_binding_context, class).expect(
                    "We should always find the surrounding class \
                     for an implicit self: Self annotation",
                );

                if self.is_classmethod(db) {
                    Some(SubclassOfType::from(
                        db,
                        SubclassOfInner::TypeVar(typing_self),
                    ))
                } else {
                    Some(Type::TypeVar(typing_self))
                }
            } else {
                // If skip creating the typevar, we use "instance of class" or "subclass of
                // class" as the implicit annotation instead.
                if self.is_classmethod(db) {
                    Some(SubclassOfType::from(
                        db,
                        SubclassOfInner::Class(ClassType::NonGeneric(class_literal)),
                    ))
                } else {
                    Some(class_literal.to_non_generic_instance(db))
                }
            }
        });

        raw_signature
    }