Repository: godot
Issue: `UNSAFE_CAST` warning is useless or has confusing description
Labels: discussion,topic:gdscript

### Tested versions

I noticed this regression when opening my project (previously 4.2.2) in v4.3.rc1.mono.official [e343dbbcc]

### System information

Windows 10 64-bit

### Issue description

I have most of the GDScript-related settings turned to errors or warnings in my project, because when they behave reasonably I find these warnings and errors to be very helpful in catching my mistakes as soon as I write them instead of later on at runtime.

Recently I opened up my project in 4.3-rc1 and noticed some new UNSAFE_CAST errors that were not present with 4.2.2. In particular this is happening wherever I was using `some_variant as [Type]`. This happens with both classes (nullable) and with primitives/value types (not nullable).

Here's an example of an affected function. The line `var point := intersection as Vector3` now produces the error `Casting "Variant" to "Vector3" is unsafe. (Warning treated as error.)`.

```
func get_ray_intersection_xz(
    ray_origin: Vector3,
    ray_normal: Vector3,
) -> Variant:
    var plane := self.get_plane_xz()
    var intersection: Variant = plane.intersects_ray(ray_origin, ray_normal)
    if intersection == null:
        return null
    var point := intersection as Vector3
    point *= self.basis.inverse()
    point -= self.global_position
    return Vector2(point.x, point.z)
```

It is possible to work around this newly occurring error by changing the line to an implicit cast instead of an explicit cast, like so:

```
    var point: Vector3 = intersection
```

This regression was apparently introduced by https://github.com/godotengine/godot/pull/84043, which closed https://github.com/godotengine/godot/issues/84027.

Discussion on the related issue suggests that casts like `variant_value as [Type]` should always be considered unsafe, but the only alternative offered is to use `type_convert`, which also cannot be used except via an implicit cast (i.e. with a variable assignment or as the typed return value of a function, not using `as`) because `type_convert` itself returns a Variant. This means that result of `type_convert` (e.g. `type_convert(intersection, TYPE_VECTOR3)` per the above example) also cannot be used type-safely except via, again, an implicit cast.

I think there really needs to be a way to explicitly convert a Variant to another typed value that does not produce a type safety error. And at some point there should probably be an UNSAFE_IMPLICIT_CAST error so that these implicit casts can also be configured to generate errors.

Ideally I would like very much to see nullable types merged for 4.3 and for casts from Variant to any nullable type to be considered safe (producing null if the Variant did not contain a value of the type being explicitly cast to), e.g. `variant_value as Vector3?` and casting to non-nullable value types to be unsafe. But until nullable types are a thing, I would rather still be able to write `variant_value as [Type]` to explicitly mark intentional casts, rather than be required to use implicit casts to work around the error, or have to turn the UNSAFE_CAST error/warning off entirely and lose its benefits in other situations. https://github.com/godotengine/godot/pull/76843

In my opinion, adding built-in functions such as `int_convert`, `float_convert`, `vector3_convert`, etc. for each possible type to use instead of casting with `as` would also be an acceptable resolution, albeit not an ideal one, with these functions returning the corresponding types directly rather than returning a Variant as with `type_convert`.

(Edit: Oh, when writing the above, I assumed that invalid casts like `0 as String` also produced an UNSAFE_CAST error/warning, but it seems that this case produces a different "Invalid cast" error and UNSAFE_CAST doesn't actually apply to anything except Variants. I guess it's unclear what benefit this error/warning has in any case, then, if it forbids implicit casts but not explicit casts, and if it's unsafe now even to cast a Variant to a reference (nullable) type?)

### Steps to reproduce

Minimum reproduction:

Turn on UNSAFE_CAST warnings/errors in project settings:

![image](https://github.com/user-attachments/assets/7277712a-103b-4c40-a731-d7cad7ae330a)

An UNSAFE_CAST warning or error will occur for line 3 of this GDScript code:

```
func _ready() -> void:
    var value: Variant = Vector2.ONE
    var vector: Vector2 = value as Vector2
```

### Minimal reproduction project (MRP)

See trivial reproduction steps