I didn't want to immediately declare this a compiler/runtime bug
without making sure I wasn't crazy/misinterpreting things.
Backstory is this: I was writing a library for dealing with some
special corporate data to (de)serialize to/from a binary format
and tweaking things to get the output to match a known good
implementation in C#. I had a unittest set up to round-trip data
from binary -> class instance -> back to binary and ensure input
and output match.
At one point I got an assert failure in an odd place; it seemed
to be coming from inside std.format.format. So I wrote a simple
test program to recreate the issue:
---
#!/usr/bin/env dub
/+ dub.sdl:
name "hello"
+/
import std.stdio;
import std.datetime;
import std.regex;
import std.base64;
import std.string;
import std.algorithm;
private immutable string[] months = ["Jan", "Feb", "Mar", "Apr",
"May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
void main()
{
string dstr = "29-Apr-2019 11:04";
SysTime dateProgrammed;
ubyte[] full = new ubyte[128];
auto m = matchFirst(dstr,
regex(r"([0-9]{2})-([A-Z][a-z]{2})-([0-9]{4})
([0-9]{2}):([0-9]{2})"));
assert(m.length > 0, "Date string is invalid");
import std.conv: to;
DateTime d = DateTime(1990, 1, 1);
d.month = to!Month(months.join.indexOf(m[2])/3+1);
d.year = m[3].to!short;
d.day = m[1].to!ubyte;
d.hour = m[4].to!ubyte;
d.minute = m[5].to!ubyte;
dateProgrammed = SysTime(d, 0.seconds);
copy("test_string".representation, full[8..16]);
import std.format: format;
string date = format!("%d-%3s-%d
%02d:%02d")(dateProgrammed.day,
months[dateProgrammed.month-1], dateProgrammed.year,
dateProgrammed.hour, dateProgrammed.minute);
copy(date.representation, full[24..44]);
Base64.encode(full).writeln;
}
---
The problem is on line 33, the copy of "test_string". The slice
to copy it into is too short. But when I run it with dub, the
output is this:
---
core.exception.AssertError@C:\D\dmd2\windows\bin\..\..\src\phobos\std\algorithm\mutation.d(373):
Cannot copy a source range into a smaller target range.
0x0043BE49 in _d_assert_msg
0x0040252B in _Dmain at \test_format_assert.d(36)
0x0043B96B in void rt.dmain2._d_run_main(int, char**, extern (C)
int function(char[][])*).runAll().__lambda1()
0x0043B8ED in void rt.dmain2._d_run_main(int, char**, extern (C)
int function(char[][])*).runAll()
0x0043B787 in _d_run_main
0x0043B518 in main at \test_format_assert.d(7)
0x0048CED5 in mainCRTStartup
0x767A0419 in BaseThreadInitThunk
0x7730662D in RtlGetAppContainerNamedObjectPath
0x773065FD in RtlGetAppContainerNamedObjectPath
---
The error was on line 36, which is the format, not my bad slice.
Is there a reason for this, or is it a bug somewhere?