Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maybe not a bug. Safety: Cannot cast nullable value to not nullable type with Std.instance #17

Open
restorer opened this issue Oct 29, 2018 · 3 comments

Comments

@restorer
Copy link

class SomeClass {
    public function new() {}
}

class MaybeBug12 {
    public function bug() : Void {
        var a = new SomeClass();

        // Safety: Cannot cast nullable value to not nullable type.
        // Probably this is not a bug in Safety, and this issue related to Std.instance() signature
        var b : Null<SomeClass> = Std.instance(a, SomeClass);
    }
}

See https://github.com/restorer/haxe-safety-bugs/blob/master/safetybugs/Main.hx#L163 for working example.

@restorer
Copy link
Author

This is for Haxe 4.0.0-preview.5 and Safety from master.

@RealyUniqueName
Copy link
Owner

This is an intended behavior for a typed cast:

static function cast_nullableExprToNotNullableType_shouldFail() {
var s:Null<String> = 'hello';
shouldFail((s:String));
shouldFail(cast(s, String));
}

However, Std.instance() uses an untyped cast, which should ignore null safety checks:

static function untypedCast_shouldPass() {
var n:Null<String> = 'hello';
var s:String = cast n;
}

Maybe Haxe typer makes them indistinguishable for the Safety plugin in case of Std.instance()

@restorer
Copy link
Author

restorer commented Oct 29, 2018

I think problem is in Std.instance signature, which is

public static function instance<T:{},S:T>( value : T, c : Class<S> ) : S;

However, documentation says:

This method checks if a downcast is possible. That is, if the runtime type of value is assignable to the class specified by c, value is returned. Otherwise null is returned.

Proper signature should be

public static function instance<T:{},S:T>( value : T, c : Class<S> ) : Null<S>;

I "fix" this by

@:safety(unsafe)
public static function instanceExt<T : {}, S : T>(value : T, c : Class<S>) : Null<S> {
    return Std.instance(value, c);
}

I understand that this is something not on Safety side, but maybe you can propose this change for Haxe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants