Thread overview
Comparison of struct with Nullable member
Jul 17, 2015
TC
Jul 17, 2015
Nicholas Wilson
Jul 17, 2015
Meta
Jul 17, 2015
TC
Jul 17, 2015
Meta
Jul 17, 2015
anonymous
July 17, 2015
Hello,
I came around a strange behavior and I'm not sure if it is a bug or feature.

import std.typecons : Nullable;
struct Foo
{
	string bar;
	Nullable!int baz;
}

auto a = Foo("bb");
auto b = Foo("bb");
assert(a == b);

This ends up with: Called `get' on null Nullable!int

But if I change bar to be an int for example, than it passes ok.
I would expect this to pass ok.

Tested on dmd 2.067.1 win64
July 17, 2015
On Friday, 17 July 2015 at 12:18:56 UTC, TC wrote:
> Hello,
> I came around a strange behavior and I'm not sure if it is a bug or feature.
>
> import std.typecons : Nullable;
> struct Foo
> {
> 	string bar;
> 	Nullable!int baz;
> }
>
> auto a = Foo("bb");
> auto b = Foo("bb");
> assert(a == b);
>
> This ends up with: Called `get' on null Nullable!int
>
> But if I change bar to be an int for example, than it passes ok.
> I would expect this to pass ok.
>
> Tested on dmd 2.067.1 win64

what is happening is the complier generated default opEquals is accessing the payload for Nullable!T without checking for null (which as you've written `Foo("bb")` this constructs a and b as `Foo("bb",(Nullable!int).init)` i.e. in the null state)

why nullables don't automatically check for null when comparing for equality idk.

you can make this work by defining your own opEquals that explicitly checks for nulls.


July 17, 2015
On Friday, 17 July 2015 at 12:18:56 UTC, TC wrote:
> Hello,
> I came around a strange behavior and I'm not sure if it is a bug or feature.
>
> import std.typecons : Nullable;
> struct Foo
> {
> 	string bar;
> 	Nullable!int baz;
> }
>
> auto a = Foo("bb");
> auto b = Foo("bb");
> assert(a == b);
>
> This ends up with: Called `get' on null Nullable!int
>
> But if I change bar to be an int for example, than it passes ok.
> I would expect this to pass ok.
>
> Tested on dmd 2.067.1 win64

https://issues.dlang.org/show_bug.cgi?id=14804

I'll probably be able to submit a PR for this sometime in the next few days.
July 17, 2015
On Friday, 17 July 2015 at 15:30:42 UTC, Meta wrote:
> https://issues.dlang.org/show_bug.cgi?id=14804
>
> I'll probably be able to submit a PR for this sometime in the next few days.

Thanks.
What I don't get is why this one works ok?

import std.typecons : Nullable;
struct Foo
{
	int bar;
	Nullable!int baz;
}
auto a = Foo(1);
auto b = Foo(1);
assert(a == b);

Also is there some "nicer" way to init the struct with nullable member with default constructor?
Now I'm using Foo(1, Nullable!int(2)) but just Foo(1, 2) would be much nicer.
Same with calling functions with nullable params.
July 17, 2015
On Friday, 17 July 2015 at 15:52:45 UTC, TC wrote:
> On Friday, 17 July 2015 at 15:30:42 UTC, Meta wrote:
>> https://issues.dlang.org/show_bug.cgi?id=14804
>>
>> I'll probably be able to submit a PR for this sometime in the next few days.
>
> Thanks.
> What I don't get is why this one works ok?
>
> import std.typecons : Nullable;
> struct Foo
> {
> 	int bar;
> 	Nullable!int baz;
> }
> auto a = Foo(1);
> auto b = Foo(1);
> assert(a == b);

This may be because if your struct only contains primitive values, the compiler will just do a memcmp to determine equality. Don't quote me on that though.

> Also is there some "nicer" way to init the struct with nullable member with default constructor?
> Now I'm using Foo(1, Nullable!int(2)) but just Foo(1, 2) would be much nicer.
> Same with calling functions with nullable params.

You can defined a custom constructor in Foo which will construct the Nullable.

struct Foo
{
    this(int n1, int n2)
    {
        bar = n1;
        baz = n2;
    }

    //...
}
July 17, 2015
On Friday, 17 July 2015 at 12:18:56 UTC, TC wrote:
> Hello,
> I came around a strange behavior and I'm not sure if it is a bug or feature.
>
> import std.typecons : Nullable;
> struct Foo
> {
> 	string bar;
> 	Nullable!int baz;
> }
>
> auto a = Foo("bb");
> auto b = Foo("bb");
> assert(a == b);
>
> This ends up with: Called `get' on null Nullable!int
>
> But if I change bar to be an int for example, than it passes ok.
> I would expect this to pass ok.
>
> Tested on dmd 2.067.1 win64

Bug. I reported a reduced version as <https://issues.dlang.org/show_bug.cgi?id=14806>.