Bug 10056 – Strange Error with templates and string.format
Status
RESOLVED
Resolution
FIXED
Severity
regression
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-05-10T04:55:00Z
Last change time
2013-05-11T15:08:55Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
puneet
Comments
Comment #0 by puneet — 2013-05-10T04:55:53Z
The following code compiles and runs well with version dmd-2.062.
Now I am compiling the following code with current github/master snapshot:
commit cfb631d40fe708fe04c54402fca8e0a72a2b850f
Merge: 526b57d aa70fab
Author: Martin Nowak <[email protected]>
Date: Fri May 10 01:34:12 2013 -0700
I get an error:
$ rdmd --force foo.d
...... /github-d/bin/../phobos/std/range.d(611): Error: static assert "Cannot put a dchar into a Appender!(string)"
I have tried minimizing this strange testcase, but could not go any further. For example, if I comment out lines 2 to 4, dmd compiles the code without an issue.
template Foo(T, U, string OP) { // 1
static if(T.ISEMPTY && U.ISEMPTY) // 2
enum bool S = false; // 3
else // 4
enum bool S = false;
alias Foo!(false, false, 0) Foo;
}
struct Foo(bool S, bool L, string VAL) {
enum bool ISEMPTY = S;
}
template Foo(T) {
alias Foo!(false, false, T.sizeof*8) Foo;
}
template Frop(size_t N) {
alias Foo!(false, false, N) Frop;
}
struct Foo(bool S, bool L, size_t N) {
import std.format;
void bar(ref FormatSpec!char f) {}
string bar() {
import std.string;
format("%b", 0);;
return "";
}
public bool opEquals(T)(T other) {
alias Foo!(typeof(this), T, "CMP") P;
return false;
}
}
void main() {
alias Frop!1 Zoo;
enum Zoo ZOO=Zoo.init;
}
Comment #1 by k.hara.pg — 2013-05-11T06:29:15Z
This regression is caused by the commit:
https://github.com/D-Programming-Language/dmd/commit/596c1128f4de2b246d339497e1bcec70d93ffd78
Reduced test case:
-------
void main()
{
alias Zoo = Foo!(false, false, 1);
}
struct Foo(bool S, bool L, size_t N)
{
string bar()
{
Appender!(string) w;
char[] buf; put(w, buf);
return "";
}
public bool opEquals(T)(T other)
{
alias Foo!(typeof(this), T, "CMP") P;
return false;
}
}
template Foo(T, U, string OP)
{
static if (T.ISEMPTY && U.ISEMPTY)
enum bool S = false;
else
enum bool S = false;
alias Foo = Foo!(false, false, 0);
}
/**********************************************/
void put(R, E)(ref R r, E e)
{
static if (is(typeof(r.put(e))))
{
r.put(e);
}
else
{
static assert(false, "Cannot put a "~E.stringof~" into a "~R.stringof);
}
}
struct Appender(A : T[], T)
{
private template canPutItem(U)
{
enum bool canPutItem = is(U : T);
}
private template canPutRange(R)
{
enum bool canPutRange = is(typeof(Appender.init.put(R.init[0])));
}
void put(U)(U item) if (canPutItem!U)
{
char[T.sizeof == 1 ? 4 : 2] encoded;
put(encoded[]);
}
void put(R)(R items) if (canPutRange!R)
{
}
}