Restrictive casting check for imputer

### Describe the bug

Hello :)

I tried using the SimpleImputer and stumbled upon a probably undesired behaviour (at least a behaviour I wish I had the hand on).

I had a column containing only integers with an integer dtype (FYI, an integer column can't contains np.nan)) that I was trying to Impute by filling it with a constant float value. However, because of `same_kind` cast check here https://github.com/scikit-learn/scikit-learn/blob/main/sklearn/impute/_base.py#L423-L425, this raises the following error.

```
ValueError: fill_value=0.0 (of type <class 'numpy.float32'>) cannot be cast to the input data that is dtype('int64'). If fill_value is a Python scalar, instead pass  a numpy scalar (e.g. fill_value=np.uint8(0) if your data is of type np.uint8). Make sure that both dtypes are of the same kind.
```

 Indeed, we have the following checks

```python
import numpy as np

np.can_cast(from_=np.float32, to=np.int64, casting="same_kind")
# False <= in this case, sklearn raises an error that's blocking my generic pipelines
np.can_cast(from_=np.int64, to=np.float32, casting="same_kind")
# True
np.can_cast(from_=np.float32, to=np.int64, casting="unsafe")
# True
```

which makes total sense.

Because I'm trying to write generic pipelines, I'd like to allow for unsafe type casting for the fill_value. This could be done by adding an option in the SimpleImputer `allow_fill_value_unsafe_casting` (quite verbose, but at least explicit). If True, the `casting` argument of `np.can_cast` would be `unsafe`.

### Steps/Code to Reproduce

```
import numpy as np
from sklearn.impute import SimpleImputer

X = np.array([1, 2, 3], dtype=np.int64)
imputer = SimpleImputer(strategy='constant', fill_value=np.float32(0))
imputer.fit(X.reshape(-1, 1))
```

### Expected Results

I expect this thing to work properly

### Actual Results

```
428     # print("fill_value_dtype", fill_value_dtype)
    429     # print("X.dtype", X.dtype)
    430     # Make sure we can safely cast fill_value dtype to the input data dtype
    431     if not np.can_cast(fill_value_dtype, X.dtype, casting="same_kind"):
--> [432](https://file+.vscode-resource.vscode-cdn.net/Users/datategy/Documents/papai-ml/papai-ml-1/~/Documents/papai-ml/papai-ml-1/.venv/lib/python3.10/site-packages/sklearn/impute/_base.py:432)         raise ValueError(err_msg)
    434 return X

ValueError: fill_value=0.0 (of type <class 'numpy.float32'>) cannot be cast to the input data that is dtype('int64'). If fill_value is a Python scalar, instead pass  a numpy scalar (e.g. fill_value=np.uint8(0) if your data is of type np.uint8). Make sure that both dtypes are of the same kind.
```

### Versions

```shell
System:
    python: 3.10.11 (v3.10.11:7d4cc5aa85, Apr  4 2023, 19:05:19) [Clang 13.0.0 (clang-1300.0.29.30)]
executable: /Users/datategy/Documents/papai-ml/papai-ml-1/.venv/bin/python
   machine: macOS-14.4.1-arm64-arm-64bit

Python dependencies:
      sklearn: 1.7.2
          pip: 25.3
   setuptools: 65.5.0
        numpy: 1.26.4
        scipy: 1.13.1
       Cython: None
       pandas: 1.5.3
   matplotlib: 3.8.4
       joblib: 1.5.2
threadpoolctl: 3.6.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 8
         prefix: libopenblas
       filepath: /Users/datategy/Documents/papai-ml/papai-ml-1/.venv/lib/python3.10/site-packages/numpy/.dylibs/libopenblas64_.0.dylib
        version: 0.3.23.dev
threading_layer: pthreads
   architecture: armv8

       user_api: blas
   internal_api: openblas
    num_threads: 8
         prefix: libopenblas
       filepath: /Users/datategy/Documents/papai-ml/papai-ml-1/.venv/lib/python3.10/site-packages/scipy/.dylibs/libopenblas.0.dylib
        version: 0.3.27
threading_layer: pthreads
   architecture: neoversen1

       user_api: openmp
   internal_api: openmp
    num_threads: 8
         prefix: libomp
       filepath: /Users/datategy/Documents/papai-ml/papai-ml-1/.venv/lib/python3.10/site-packages/sklearn/.dylibs/libomp.dylib
        version: None
```

COMMENT:
To have a generic pipeline, you could have a custom transformer, which takes the fill value and the X, and convert X to the type of fill value, or other way around, and then your pipeline is generic enough.

Labels: Bug, Needs Triage