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

ability to compare a pointer with a nullable pointer #658

Closed
andrewrk opened this Issue Dec 15, 2017 · 3 comments

Comments

Projects
None yet
2 participants
@andrewrk
Member

andrewrk commented Dec 15, 2017

The == and != operators should work when the LHS and RHS are any combination of &T and ?&T.

@andrewrk andrewrk added this to the 0.2.0 milestone Dec 15, 2017

@andrewrk

This comment has been minimized.

Member

andrewrk commented Dec 15, 2017

@andrewrk andrewrk modified the milestones: 0.2.0, 0.3.0 Jan 6, 2018

@thejoshwolfe

This comment has been minimized.

Member

thejoshwolfe commented Jan 23, 2018

I propose comparisons work with ?T whenever they would work T. Consider:

var maybe: ?bool = null;
if (maybe != false) {
    // ...
}

(Furthermore, the error message you get is pretty misleading, error: operator not allowed for type '?bool'. But comparisons do work with type ?bool if you're comparing against null.)

The motivation for this issue is that the current workaround is nominally suboptimal performance due to having two conditional branches instead of just one:

if (!(maybe != null and (maybe ?? unreachable) == false)) {
    // ...
}
// or
if (!if (maybe) |value| value == false else false) {
    // ...
}

For nullable types that are implemented to fit into a single word (like nullable pointers and bools), the optimal assembly would be a single comparison instruction, which looks more like maybe != false than the workaround above.

@andrewrk

This comment has been minimized.

Member

andrewrk commented Jan 23, 2018

This looks reasonable to me:

var maybe: ?bool = null;
if (maybe ?? true) {

}

The performance argument isn't valid. Currently, the above code generates

struct {
    payload: bool,
    non_null: bool,
}

And so doing the comparison is 2 comparisons. If we were to represent the data in a different way, such as this:

enum {
    Null,
    False,
    True,
}

Then the above code could generate a single comparison, even in debug mode. (And assigning a value becomes a more complicated transformation than writing {value, true} to a struct).

Contrast this with nullable pointers (and nullable function pointers), where they are guaranteed to be represented as a usize in memory, with the 0 value for null.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment