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

Code before:
    /// If no bound is present, falls back to `object`.
    /// For constraints, uses the first constraint as a representative class for subclass checking.
    ///
    /// Returns `None` for unrecognized bound types (e.g., `Callable`, structural protocols).
    fn bound_class(
        bound_typevar: BoundTypeVarInstance<'db>,
        db: &'db dyn Db,
    ) -> Option<ClassType<'db>> {
        match bound_typevar.typevar(db).bound_or_constraints(db) {
            Some(TypeVarBoundOrConstraints::UpperBound(bound)) => match bound {
                Type::NominalInstance(instance) => Some(instance.class(db)),
                _ => bound.to_class_type(db),
            },
            Some(TypeVarBoundOrConstraints::Constraints(constraints)) => {
                // For constraints, use the first constraint as a representative class.
                // This is used for subclass checking - if the first constraint is not
                // a subclass of the pivot, the super() call will fail validation.
                constraints
                    .elements(db)
                    .first()
                    .and_then(|first| match first {
                        Type::NominalInstance(instance) => Some(instance.class(db)),
                        _ => first.to_class_type(db),
                    })
            }
            None => KnownClass::Object.to_class_literal(db).to_class_type(db),
        }
    }

    fn normalized_impl(self, db: &'db dyn Db, visitor: &NormalizedVisitor<'db>) -> Self {
        match self {
            SuperOwnerKind::Dynamic(dynamic) => SuperOwnerKind::Dynamic(dynamic.normalized()),
            SuperOwnerKind::Class(class) => {
                SuperOwnerKind::Class(class.normalized_impl(db, visitor))
            }
            SuperOwnerKind::Instance(instance) => instance
                .normalized_impl(db, visitor)
                .as_nominal_instance()
                .map(Self::Instance)
                .unwrap_or(Self::Dynamic(DynamicType::Any)),
            SuperOwnerKind::InstanceTypeVar(bound_typevar) => {
                SuperOwnerKind::InstanceTypeVar(bound_typevar.normalized_impl(db, visitor))
            }
            SuperOwnerKind::ClassTypeVar(bound_typevar) => {
                SuperOwnerKind::ClassTypeVar(bound_typevar.normalized_impl(db, visitor))
            }
        }
    }

    fn recursive_type_normalized_impl(
        self,

Review comment (suggestion):
```suggestion
            None => ClassType::object(db),
```

Code after:
            SuperOwnerKind::Dynamic(dynamic) => SuperOwnerKind::Dynamic(dynamic.normalized()),
            SuperOwnerKind::Class(class) => {
                SuperOwnerKind::Class(class.normalized_impl(db, visitor))
            }
            SuperOwnerKind::Instance(instance) => instance
                .normalized_impl(db, visitor)
                .as_nominal_instance()
                .map(Self::Instance)
                .unwrap_or(Self::Dynamic(DynamicType::Any)),
            SuperOwnerKind::InstanceTypeVar(bound_typevar, class) => {
                SuperOwnerKind::InstanceTypeVar(
                    bound_typevar.normalized_impl(db, visitor),
                    class.normalized_impl(db, visitor),
                )
            }
            SuperOwnerKind::ClassTypeVar(bound_typevar, class) => SuperOwnerKind::ClassTypeVar(
                bound_typevar.normalized_impl(db, visitor),
                class.normalized_impl(db, visitor),
            ),
        }
    }

    fn recursive_type_normalized_impl(
        self,
        db: &'db dyn Db,
        div: Type<'db>,
        nested: bool,
    ) -> Option<Self> {
        match self {
            SuperOwnerKind::Dynamic(dynamic) => {
                Some(SuperOwnerKind::Dynamic(dynamic.recursive_type_normalized()))
            }
            SuperOwnerKind::Class(class) => Some(SuperOwnerKind::Class(
                class.recursive_type_normalized_impl(db, div, nested)?,
            )),
            SuperOwnerKind::Instance(instance) => Some(SuperOwnerKind::Instance(
                instance.recursive_type_normalized_impl(db, div, nested)?,
            )),
            SuperOwnerKind::InstanceTypeVar(_, _) | SuperOwnerKind::ClassTypeVar(_, _) => {
                // TODO: we might need to normalize the nested class here?
                Some(self)
            }
        }
    }

    fn iter_mro(self, db: &'db dyn Db) -> impl Iterator<Item = ClassBase<'db>> {
        match self {
            SuperOwnerKind::Dynamic(dynamic) => {
                Either::Left(ClassBase::Dynamic(dynamic).mro(db, None))
            }
            SuperOwnerKind::Class(class) => Either::Right(class.iter_mro(db)),