-
-
Notifications
You must be signed in to change notification settings - Fork 706
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
Fix issue 14925 -- narrow strings should not match the first overload of replaceInPlace. #3561
Conversation
|
I think we don't have to keep two overloaded functions for The purpose of the first overload of void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff)
if (is(typeof(replace(array, from, to, stuff))))
// <-- `replaceInPlace` has equivalent constraint with the one that `replace` has
{
static if ( isMutable!T &&
!isNarrowString!(T[]) &&
isDynamicArray!Range &&
is(Unqual!(ElementEncodingType!Range) == T))
// <-- elabolate internal constraint for the optimized code
{
// [snip]
// <-- the body of first overload
}
else
{
array = replace(array, from, to, stuff);
// <-- the body of second overload
}
}
/// Ditto <-- can be removed
//void replaceInPlace(T, Range)(ref T[] array, size_t from, size_t to, Range stuff)
//{
//} |
|
Yes, I think this is an appropriate way to refactor, will do. |
with template instantiation. Also, preclude narrow strings and other invalid combinations (e.g. long[] and int[]) from being selected for optimized path.
|
Done |
|
Some whitespace changes, use this link to view without the whitespace changes: #3561 |
| static if(isDynamicArray!Range && | ||
| is(Unqual!(ElementEncodingType!Range) == T) && | ||
| !is(T == const T) && | ||
| !is(T == immutable T) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think an unlisted bug exists here. If T is inout type, it would accidentally go into this optimized pass.
I'd suggest to use isMutable!T.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But, it can be separated issue. I'd go forward this improvement PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote this in unit test, and it didn't fail:
void foo(inout(int)[] x)
{
x.replaceInPlace(1,2, [1,2,3]);
}Not sure if I did that right, I agree it probably should match the static if.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hah, I know why it works :) In fact, I think possibly we don't even need the isMutable: the Unqual call will make sure I am testing the mutable version of the element type against T, and this will only succeed if T is mutable. A happy accident!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I also confirmed that. So we can also remove the check !is(T == const T) && !is(T == immutable T). Hooray!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened #3565 for the supplemental fix.
|
Auto-merge toggled on |
Fix issue 14925 -- narrow strings should not match the first overload of replaceInPlace.
Also, fixed issues with non-compatible arrays matching the first overload.
Note the rewritten constraint of the second version. It was getting very hairy, so I just decided on a strategy of "it doesn't match the first, and I can call replace, so do it"