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

Code before:
    db: &'db dyn Db,
    bound_super: BoundSuperType<'db>,
    visitor: &V,
) {
    visitor.visit_type(db, Type::from(bound_super.pivot_class(db)));
    visitor.visit_type(db, bound_super.owner(db).binding_type(db));
}

impl<'db> BoundSuperType<'db> {
    /// Attempts to build a `Type::BoundSuper` based on the given `pivot_class` and `owner`.
    ///
    /// This mimics the behavior of Python's built-in `super(pivot, owner)` at runtime.
    /// - `super(pivot, owner_class)` is valid only if `issubclass(owner_class, pivot)`
    /// - `super(pivot, owner_instance)` is valid only if `isinstance(owner_instance, pivot)`
    ///
    /// However, the checking is skipped when any of the arguments is a dynamic type.
    pub(super) fn build(
        db: &'db dyn Db,
        pivot_class_type: Type<'db>,
        owner_type: Type<'db>,
    ) -> Result<Type<'db>, BoundSuperError<'db>> {
        let delegate_to =
            |type_to_delegate_to| BoundSuperType::build(db, pivot_class_type, type_to_delegate_to);

        let delegate_with_error_mapped =
            |type_to_delegate_to, error_context: Option<TypeVarInstance<'db>>| {
                delegate_to(type_to_delegate_to).map_err(|err| match err {
                    BoundSuperError::AbstractOwnerType {
                        owner_type: _,
                        pivot_class: _,
                        typevar_context: _,
                    } => BoundSuperError::AbstractOwnerType {
                        owner_type,
                        pivot_class: pivot_class_type,
                        typevar_context: error_context,
                    },
                    BoundSuperError::FailingConditionCheck {
                        pivot_class,
                        owner: _,
                        typevar_context: _,
                    } => BoundSuperError::FailingConditionCheck {
                        pivot_class,
                        owner: owner_type,
                        typevar_context: error_context,
                    },
                    BoundSuperError::InvalidPivotClassType { pivot_class } => {
                        BoundSuperError::InvalidPivotClassType { pivot_class }
                    }
                    BoundSuperError::UnavailableImplicitArguments => {
                        BoundSuperError::UnavailableImplicitArguments
                    }

Review comment (refactor):
In the current code in this PR, we never pass in a non-None `error_context` here. Maybe this will change if we fix the lost error context; if it doesn't, we should simplify this method (we probably only need `delegate_to` in that case, not `delegate_with_error_mapped`)

Code after:
    visitor.visit_type(db, Type::from(bound_super.pivot_class(db)));
    visitor.visit_type(db, bound_super.owner(db).owner_type(db));
}

impl<'db> BoundSuperType<'db> {
    /// Attempts to build a `Type::BoundSuper` based on the given `pivot_class` and `owner`.
    ///
    /// This mimics the behavior of Python's built-in `super(pivot, owner)` at runtime.
    /// - `super(pivot, owner_class)` is valid only if `issubclass(owner_class, pivot)`
    /// - `super(pivot, owner_instance)` is valid only if `isinstance(owner_instance, pivot)`
    ///
    /// However, the checking is skipped when any of the arguments is a dynamic type.
    pub(super) fn build(
        db: &'db dyn Db,
        pivot_class_type: Type<'db>,
        owner_type: Type<'db>,
    ) -> Result<Type<'db>, BoundSuperError<'db>> {
        let delegate_to =
            |type_to_delegate_to| BoundSuperType::build(db, pivot_class_type, type_to_delegate_to);

        // Delegate but rewrite errors to preserve TypeVar context.
        let delegate_with_error_mapped =
            |type_to_delegate_to, error_context: Option<TypeVarInstance<'db>>| {
                delegate_to(type_to_delegate_to).map_err(|err| match err {
                    BoundSuperError::AbstractOwnerType {
                        owner_type: _,
                        pivot_class: _,
                        typevar_context: _,
                    } => BoundSuperError::AbstractOwnerType {
                        owner_type,
                        pivot_class: pivot_class_type,
                        typevar_context: error_context,
                    },
                    BoundSuperError::FailingConditionCheck {
                        pivot_class,
                        owner: _,
                        typevar_context: _,
                    } => BoundSuperError::FailingConditionCheck {
                        pivot_class,
                        owner: owner_type,
                        typevar_context: error_context,
                    },
                    BoundSuperError::InvalidPivotClassType { pivot_class } => {
                        BoundSuperError::InvalidPivotClassType { pivot_class }
                    }
                    BoundSuperError::UnavailableImplicitArguments => {
                        BoundSuperError::UnavailableImplicitArguments
                    }
                })
            };