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
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/65b1f1af77b099ab97c94d802f027fa89cef0165 Fix Issue 18615 - Rebindable!A calls A.opEquals The issue was that Rebindable!A always compared two rebindable references by 'a is b', not by A.opEquals. With this fix, two rebindable references, or a rebindable and a raw reference, always compare with A.opEquals. https://github.com/dlang/phobos/commit/9de28234bff85df508890f3b202515b63e590319 Merge pull request #6370 from SimonN/issue18615 Fix Issue 18615 - Rebindable!A calls A.opEquals merged-on-behalf-of: Jack Stouffer <[email protected]>