Bug 18615 – Rebindable!A doesn't use class A's opEquals (returns a is b instead)
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2018-03-15T04:57:15Z
Last change time
2018-04-05T20:21:28Z
Keywords
pull
Assigned to
Simon Naarmann
Creator
Simon Naarmann
Comments
Comment #0 by eiderdaus — 2018-03-15T04:57:15Z
DMD64 D Compiler v2.079.0
The Phobos docs for Rebindable say: "Rebindable!(Widget) does allow reassignment, while otherwise behaving exactly like a const Widget."
Source: https://dlang.org/library/std/typecons/rebindable.html
The following code violates "behaving exactly like a const Widget": Even though class A overrides opEquals, the Rebindable!(const(A)) doesn't call A.opEquals.
#!/usr/bin/rdmd
import std.typecons;
class C {
int x;
override bool opEquals(Object rhsObj)
{
const(C) rhs = cast(const(C)) rhsObj;
return this.x == rhs.x;
}
}
void main()
{
C a = new C();
C b = new C();
assert (a == b); // OK: Even though a !is b, we overrode opEquals
// and compare a.x == b.x, which is true (0 == 0).
Rebindable!(const(C)) ca = a;
Rebindable!(const(C)) cb = b;
assert (ca == cb); // Fails! struct Rebindable doesn't forward its
// opEquals to the class's opEquals!
}
Rebindable!(const(A)).opEquals seems to return true iff the references point to the same const(A).
Is this a bug in Rebindable's implementation, or is this by design and should be documented? If it's by design, that's very surprising though and has caught me several times.
-- Simon
Comment #1 by greeenify — 2018-03-15T05:35:08Z
Imho this is a bug. I can't even think about a good use case where the current behavior would be preferred.
Comment #2 by eiderdaus — 2018-03-28T11:47:44Z
Thanks, I'll take a crack at this then because nobody considers it a feature. The fix looks obvious to me and I've always wanted to contribute to D.
Comment #3 by greensunny12 — 2018-03-28T12:01:49Z
BTW Nullable seems to have had a similar flaw, might be worthwhile to look at briefly:
https://github.com/dlang/phobos/pull/5032
> Thanks, I'll take a crack at this then because nobody considers it a feature. The fix looks obvious to me and I've always wanted to contribute to D.
Cool! Please let us know if you hit any road bumps etc. ;-)
Comment #4 by eiderdaus — 2018-03-29T09:08:59Z
I've got a PR for Phobos ready at:
https://github.com/dlang/phobos/pull/6370
The root cause was that union equality is always bitwise. The compiler issue is 15828, and the consensus seems that implicit union comparison should be a compiler error:
https://issues.dlang.org/show_bug.cgi?id=15828
My PR for 18615 works independently of 15828 because I compare the class reference inside the union explicitly with == against rhs's class reference.
> Cool! Please let us know if you hit any road bumps etc. ;-)
Thanks, it's been smooth sailing so far!
-- Simon
Comment #5 by github-bugzilla — 2018-04-05T20:21:27Z