D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 12134 - std.string.split(string) assignment to immutable
Summary: std.string.split(string) assignment to immutable
Status: RESOLVED WORKSFORME
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords: rejects-valid
Depends on:
Blocks:
 
Reported: 2014-02-11 16:07 UTC by bearophile_hugs
Modified: 2020-03-21 03:56 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description bearophile_hugs 2014-02-11 16:07:25 UTC
I have tagged this as a D enhancement.

I'd like this code to be accepted:


void main() {
    import std.string: split;
    immutable r = "AB CD".split;
}


DMD 2.065beta2 gives:

test.d(3): Error: cannot implicitly convert expression (split("AB CD")) of type string[] to immutable(char[][])


split(string) should return a string[] that is implicitly castable to immutable(string)[] and immutable(string[]).

split comes from std.array, and the problem boils down to:


S[] split(S)(S s) pure {
    S[] result;
    return result;
}
void main() {
    char[][] r1 = "AB CD".dup.split;
    const string[] r2 = "AB CD".split;
}



This is a first try at finding a solution:


import std.traits: isMutable, Select, ForeachType;
import std.traits: isSomeString;
import std.uni: isWhite;

Select!(isMutable!(ForeachType!S), S, immutable S)[]
split(S)(S s) @safe pure
if (isSomeString!S) {
    size_t istart;
    bool inword = false;
    typeof(return) result;

    foreach (i, dchar c; s) {
        if (isWhite(c)) {
            if (inword) {
                result ~= s[istart .. i];
                inword = false;
            }
        } else {
            if (!inword) {
                istart = i;
                inword = true;
            }
        }
    }

    if (inword)
        result ~= s[istart .. $];
    return result;
}

void main() {
    string s = "AB CD";
    char[] m = s.dup;
    char[][] r1 = m.split;
    immutable r2 = s.split;
    auto r3 = s.split;
    pragma(msg, typeof(r3)); // Output: immutable(char[])[]
    const(string)[] r4 = s.split; // OK
    string[] r5 = s.split; // Error
}


The code works correctly with r1, you can assign it to a mutable array because the input is mutable.

But the problem is shown with r5, what if you instead want a mutable array of regular strings?

So, can the D type system be modified for such situations? And is it a good idea to modify it like this?
Comment 1 basile-z 2019-06-28 14:18:50 UTC
fixed since 2.066 : https://run.dlang.io/is/kjMKqT