Bug 19644 – std.range.takeOne opSlice asserts incorrectly when operating on non-forward input range
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Mac OS X
Creation time
2019-02-04T01:28:48Z
Last change time
2019-02-09T07:48:53Z
Assigned to
No Owner
Creator
Jon Degenhardt
Comments
Comment #0 by jrdemail2000-dlang — 2019-02-04T01:28:48Z
std.range.takeOne supports slicing. The valid slice is [0..1]. However, the implementation for non-forward input ranges incorrectly asserts on this call. This is due incorrectly checking for the second argument being less-than length. The test should be less-than-equal.
A PR is in progress.
--- Test program (test.d) ---
import std.range;
import std.stdio;
struct ValInputRange(R)
{
R data;
this(R _data) pure @safe nothrow { data = _data; }
@property bool empty() pure @safe nothrow { return data.empty; }
@property auto front() pure @safe nothrow { assert(!empty); return data.front; }
void popFront() pure @safe nothrow { assert(!empty); data.popFront(); }
}
auto valInputRange(R)(R range) { return ValInputRange!R(range); }
void main(string[] args)
{
auto a = [1, 2, 3, 4, 5];
auto r1 = a.takeOne;
auto q1 = r1[0..1]; // Works fine.
writeln(q1);
auto r2 = a.valInputRange.takeOne;
auto q2 = r2[0..1]; // Asserts here.
writeln(q2);
}
----------------------------
Run:
$ dmd --version
DMD64 D Compiler v2.084.0
$ dmd test.d
$ ./test
[1]
core.exception.AssertError@/INSTALLDIR/osx/bin/../../src/phobos/std/range/package.d(2658): Attempting to index a takeOne out of bounds
----------------
??:? _d_assert_msg [0x2db17d8]
??:? pure nothrow @nogc @safe std.range.takeOne!(test.ValInputRange!(int[]).ValInputRange).takeOne(test.ValInputRange!(int[]).ValInputRange).Result std.range.takeOne!(test.ValInputRange!(int[]).ValInputRange).takeOne(test.ValInputRange!(int[]).ValInputRange).Result.opSlice(ulong, ulong) [0x2da45f8]
??:? _Dmain [0x2d9867b]
Comment #1 by jrdemail2000-dlang — 2019-02-04T06:23:38Z