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

Code before:
        diag.set_concise_message(message);
    }

    // special case message
    if let Type::NominalInstance(target_instance) = target_ty {
        let db = context.db();
        let file = target_instance.class(db).class_literal(db).file(db);
        if let Some(module) = file_to_module(db, file)
            && module.is_known(db, KnownModule::Numbers)
        {
            let is_numeric = match value_ty {
                Type::IntLiteral(_) | Type::BooleanLiteral(_) => true,
                Type::NominalInstance(value_instance) => {
                    let value_class = value_instance.class(db);
                    value_class.known(db).is_some_and(|known| {
                        matches!(
                            known,
                            KnownClass::Int
                                | KnownClass::Float
                                | KnownClass::Complex
                                | KnownClass::Bool
                        )
                    })
                }
                _ => false,
            };

            if is_numeric {
                diag.info(
                    "Types from the `numbers` module aren't supported for static type checking.",
                );
                diag.help("Consider using a protocol instead, such as `typing.SupportsFloat`");
            }
        }
    }
}

pub(super) fn report_invalid_attribute_assignment(
    context: &InferContext,
    node: AnyNodeRef,
    target_ty: Type,
    source_ty: Type,
    attribute_name: &'_ str,
) {
    // TODO: Ideally we would not emit diagnostics for `TypedDict` literal arguments
    // here (see `diagnostic::is_invalid_typed_dict_literal`). However, we may have
    // silenced diagnostics during attribute resolution, and rely on the assignability
    // diagnostic being emitted here.

    report_invalid_assignment_with_message(
        context,

Review comment (suggestion):
a little simpler:

```suggestion
            let is_numeric = [KnownClass::Int, KnownClass::Float, KnownClass::Complex]
                .iter()
                .any(|numeric| value_ty.is_subtype_of(db, numeric.to_instance(db)));
```

Code after:
        diag.set_concise_message(message);
    }

    // special case message
    if let Type::NominalInstance(target_instance) = target_ty {
        let db = context.db();
        let file = target_instance.class(db).class_literal(db).file(db);
        if let Some(module) = file_to_module(db, file)
            && module.is_known(db, KnownModule::Numbers)
        {
            let is_numeric = [KnownClass::Int, KnownClass::Float, KnownClass::Complex]
                .iter()
                .any(|numeric| value_ty.is_subtype_of(db, numeric.to_instance(db)));

            if is_numeric {
                diag.info(
                    "Types from the `numbers` module aren't supported for static type checking",
                );
                diag.help("Consider using a protocol instead, such as `typing.SupportsFloat`");
            }
        }
    }
}

pub(super) fn report_invalid_attribute_assignment(
    context: &InferContext,
    node: AnyNodeRef,
    target_ty: Type,
    source_ty: Type,
    attribute_name: &'_ str,
) {
    // TODO: Ideally we would not emit diagnostics for `TypedDict` literal arguments
    // here (see `diagnostic::is_invalid_typed_dict_literal`). However, we may have
    // silenced diagnostics during attribute resolution, and rely on the assignability
    // diagnostic being emitted here.

    report_invalid_assignment_with_message(
        context,
        node,
        target_ty,
        format_args!(
            "Object of type `{}` is not assignable to attribute `{attribute_name}` of type `{}`",
            source_ty.display(context.db()),
            target_ty.display(context.db()),
        ),
    );
}

pub(super) fn report_bad_dunder_set_call<'db>(
    context: &InferContext<'db, '_>,
    dunder_set_failure: &CallError<'db>,