[Issue 21129] New: [REG2.090] std.range.only broken for reference conversions of local copies of parameters

d-bugmail at puremagic.com d-bugmail at puremagic.com
Thu Aug 6 13:45:13 UTC 2020


https://issues.dlang.org/show_bug.cgi?id=21129

          Issue ID: 21129
           Summary: [REG2.090] std.range.only broken for reference
                    conversions of local copies of parameters
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: regression
          Priority: P1
         Component: phobos
          Assignee: nobody at puremagic.com
          Reporter: johanengelen at weka.io

std.range.only was broken by this PR: https://github.com/dlang/phobos/pull/7253

The problem is that inside only there is a conversion of types if the
parameters do not all have the same type but can be converted to a common type.
After this PR, this conversion happens on the local copy and then the local
copy is thrown away (OnlyResult copies the converted value).

Example of code that broke (added some debug lines that show the pointer values
to understand what is going wrong):
```
import std.range;
import std.stdio;
import std.algorithm;

void main()
{
    // Comment-out one of the two to test the other, both are broken.
    broken_staticarray();
    broken_fixedstring();
}

void broken_staticarray()
{
    char[9] something = "something";
    writeln(__LINE__,":", cast(size_t)something.ptr);
    auto range = only("one", something, "three");
    foreach (ref v; range) {
        writeln(__LINE__,":", cast(size_t)v.ptr, " ,", v.length);
    }

    assert(only("one", something, "three").joiner(" ").equal("one something
three"));
}

struct FixedLengthArray(T, size_t capacity_)
{
    enum capacity = capacity_;

        private size_t _length;
    private T[capacity] _elems;

    this(U)(U val) {
        opAssign(val);
    }

    auto ref opAssign(U)(U[] arr) {
        _length = arr.length;
        _elems[0 .. _length] = arr;
    }

    @property inout(T)[] slice() inout nothrow @nogc pure @safe {
        return _elems[0 .. _length];
    }

    alias slice this;
}

alias FixedString = FixedLengthArray!(char, 256);

void broken_fixedstring()
{
    FixedString something = "something";
    writeln(__LINE__,":", cast(size_t)something.slice.ptr);
    auto range = only("one", something, "three");
    foreach (ref v; range) {
        writeln(__LINE__,":", cast(size_t)v.ptr, " ,", v.length);
    }

    assert(only("one", something, "three").joiner(" ").equal("one something
three"));
}
```

--


More information about the Digitalmars-d-bugs mailing list