Revise core.internal.array.equality#3142
Conversation
|
Thanks for your pull request and interest in making D better, @kinke! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + druntime#3142" |
4f2c1ce to
df01095
Compare
|
Azure CI issue for the OMF job: AFAICT, that's the DMD host compiler failing to generate a linkable d_do_test tool. A druntime change shouldn't affect this at all. The unittest failure in https://github.com/CyberShadow/ae/blob/ae2afb17cae70c8df739fb0dccd00b6eef212015/utils/regex.d#L345-L346 is somewhat worrying. I'll try to reproduce that later with LDC. |
|
Those 2 lines in the CyberShadow/ae repo nicely show the current problem with diverging behavior for Transformation expected = { type : Transformation.Type.replace, replace : { search : "from", replacement : "to", flags : "" } };
auto actual = splitRETransformation("s/from/to/");
assert(actual[0] != expected); // single element NOT equal (compiled without -preview=fieldwise)
Transformation[] expectedSlice = [expected];
assert(actual == expectedSlice); // equal (lowered to __equals); unfortunately, this is tested
Transformation[1] expectedSarray = [expected];
assert(actual != expectedSarray); // NOT equal (not lowered) |
That's probably the same issue as this one: #3141 (comment) |
Previously, the tools were compiled by the DMD host compiler, but linked with freshly compiled druntime/Phobos, leading to inevitable issues popping up in dlang/druntime#3141 and dlang/druntime#3142.
The previous test really depended on `-preview=fieldwise`. See dlang/druntime#3142 (comment).
|
The ae project has been adapted (no tagged release available yet though). See the linked PR above for more context wrt. that issue, boiling down to: union Transformation
{
string search;
}
void main()
{
static immutable from = "from", from2 = "from2";
Transformation[] a = [{ search : from }];
Transformation[] b = [{ search : from2[0..4] }];
assert(a == b);
}failing the assertion now with this PR (using memcmp ( |
|
oops, didn't know there was already something for this instead of #3151. Is there anything in this that still needs merging? I think it would need to at least be rebased now that the other PR is merged. |
|
Yeah, a rebase is now necessary, but it's still blocked by the missing new tag for @CyberShadow's |
src/core/internal/array/equality.d
Outdated
| // Use memcmp if applicable to both element types and the size matches. | ||
| static if (T1.sizeof == T2.sizeof && useMemcmp!T1 && useMemcmp!T2) |
There was a problem hiding this comment.
Need to also check __traits(isUnsigned, T1) == __traits(isUnsigned, T2) or else:
ubyte[] a = [cast(ubyte) 0xff];
byte[] b = [cast(byte) 0xff];
assert(a != b); // Currently passes but will fail after this PR.There was a problem hiding this comment.
Right, thx. That only affects integers < 32 bit though, due to int promotion.
src/core/internal/array/equality.d
Outdated
| import core.internal.traits : Unqual; | ||
| enum isVoid = is(Unqual!T == void); |
There was a problem hiding this comment.
From the perspective of the compiler frontend there anything to recommend this over is(immutable T == immutable void)?
There was a problem hiding this comment.
What about shared?
There was a problem hiding this comment.
It works since immutable(shared T) == immutable T.
There was a problem hiding this comment.
From the perspective of the compiler frontend there anything to recommend this over is(immutable T == immutable void)?
Absolutely not, thx for the suggestion.
* Use memcmp for more types (incl. pointers and some static arrays), and don't require both element types to be equivalent (e.g., use it for comparing wchar[] and ushort[] too). * Simplify the non-memcmp branch - the previous code seemed to try to do what the compiler already does. * The previous code for structs without custom opEquals basically enforced -preview=fieldwise via .tupleof comparison. This breaking change with 2.078 almost certainly wasn't intended (and not mentioned in the changelog) and led to undesirable inconsistent behavior, see dlang#3142 (comment). This reverts that change in semantics. * Avoid superfluously nested templates and convert the remaining `at()` helper to a module-level template to reduce the number of redundant instantiations.
I think everyone would agree that a fix for something like this should appear in the changelog. |
* Use memcmp for more types (incl. pointers and some static arrays), and don't require both element types to be equivalent (e.g., use it for comparing wchar[] and ushort[] too). * Simplify the non-memcmp branch - the previous code seemed to try to do what the compiler already does. * The previous code for structs without custom opEquals basically enforced -preview=fieldwise via .tupleof comparison. This breaking change with 2.078 almost certainly wasn't intended (and not mentioned in the changelog) and led to undesirable inconsistent behavior, see dlang#3142 (comment). This reverts that change in semantics. * Avoid superfluously nested templates and convert the remaining `at()` helper to a module-level template to reduce the number of redundant instantiations.
* Use memcmp for more types (incl. pointers and some static arrays), and don't require both element types to be equivalent (e.g., use it for comparing wchar[] and ushort[] too). * Simplify the non-memcmp branch - the previous code seemed to try to do what the compiler already does. * The previous code for structs without custom opEquals basically enforced -preview=fieldwise via .tupleof comparison. This breaking change with 2.078 almost certainly wasn't intended (and not mentioned in the changelog) and led to undesirable inconsistent behavior, see dlang#3142 (comment). This reverts that change in semantics. * Avoid superfluously nested templates and convert the remaining `at()` helper to a module-level template to reduce the number of redundant instantiations.
|
The |
|
Because it removed all the casting, this PR fixed this bug: https://issues.dlang.org/show_bug.cgi?id=21094. |
* Use memcmp for more types (incl. pointers and some static arrays), and don't require both element types to be equivalent (e.g., use it for comparing wchar[] and ushort[] too). * Simplify the non-memcmp branch - the previous code seemed to try to do what the compiler already does. * The previous code for structs without custom opEquals basically enforced -preview=fieldwise via .tupleof comparison. This breaking change with 2.078 almost certainly wasn't intended (and not mentioned in the changelog) and led to undesirable inconsistent behavior, see dlang#3142 (comment). This reverts that change in semantics. * Avoid superfluously nested templates and convert the remaining `at()` helper to a module-level template to reduce the number of redundant instantiations. See dlang#3142
Previously, the tools were compiled by the DMD host compiler, but linked with freshly compiled druntime/Phobos, leading to inevitable issues popping up in dlang/druntime#3141 and dlang/druntime#3142.
Previously, the tools were compiled by the DMD host compiler, but linked with freshly compiled druntime/Phobos, leading to inevitable issues popping up in dlang/druntime#3141 and dlang/druntime#3142.
wchar[]andushort[]too).opEqualsbasically enforced-preview=fieldwisevia.tupleofcomparison. This breaking change with 2.078 almost certainly wasn't intended (and not mentioned in the changelog) and led to undesirable inconsistent behavior.This reverts that change in semantics.
at()helper to a module-level template to reduce the number of redundant instantiations.