Skip to content
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

Merged
merged 1 commit into from
Aug 19, 2015

Conversation

schveiguy
Copy link
Member

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"

@9rnsr
Copy link
Contributor

9rnsr commented Aug 19, 2015

I think we don't have to keep two overloaded functions for replaceInPlace.

The purpose of the first overload of replaceInPlace is for the optimization.
And, replaceInPlace itself would take equivalent template arguments that the replace function takes.
So I think following code style would be simpler:

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)
//{
//}

@schveiguy
Copy link
Member Author

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.
@schveiguy
Copy link
Member Author

Done

@schveiguy
Copy link
Member Author

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) &&
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Member Author

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.

Copy link
Member Author

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!

Copy link
Contributor

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!

Copy link
Contributor

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.

@9rnsr
Copy link
Contributor

9rnsr commented Aug 19, 2015

Auto-merge toggled on

9rnsr added a commit that referenced this pull request Aug 19, 2015
Fix issue 14925 -- narrow strings should not match the first overload of replaceInPlace.
@9rnsr 9rnsr merged commit 4d36627 into dlang:master Aug 19, 2015
@schveiguy schveiguy deleted the fix14925 branch August 19, 2015 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants