This is a regression between DMD 2.050 and 2.051.
Several routines in std.algorithm rely on template constraints of the form: is(typeof(binaryFun!... However, since binaryFun triggers a static assert and stops compilation, there is a logical error here and causes find("goodbye","bye"), etc to not compile. This might be rooted in a change to how DMD handles is statements / static asserts, but there is a simple patch to Phobos that seems to work around this issue by adding a template constraint to binaryFunImpl in std.functional:
template binaryFunImpl(alias fun, string parm1Name, string parm2Name) {
static if (is(typeof(fun) : string)) {
enum testAsExpression = "{ ElementType1 "
~parm1Name~"; ElementType2 "
~parm2Name~"; return ("~fun~");}()";
typeof(mixin(testAsExpression))
result(ElementType1, ElementType2)(ElementType1 __a, ElementType2 __b)
if(__traits(compiles, mixin(testAsExpression)))
{
mixin("alias __a "~parm1Name~";");
mixin("alias __b "~parm2Name~";");
mixin("return (" ~ fun ~ ");");
}
} else {
alias fun result;
}
}
Comment #1 by bugzilla — 2011-02-03T00:23:39Z
Do you have a test case? I tried your example
find("goodbye", "bye");
and it works for me.
Comment #2 by sandford — 2011-02-03T09:46:11Z
I apologize for the bad test case. In retrospect, I believe I didn't try to reduce it, I simply extrapolated the issue from the error message reported. Here is a properly test case:
import std.string;
pragma(msg, replace(int.stringof,"int","real"));
Which generates the error:
C:\dmd2\src\phobos\std\functional.d(177): Error: static assert "Bad binary function q{a == b}. You need to use a valid D expression using symbols a of type dchar and b of type const(char)[]."
C:\dmd2\src\phobos\std\functional.d(180): instantiated from here: Body!(dchar,const(char)[])
C:\dmd2\src\phobos\std\algorithm.d(2149): instantiated from here: result!(dchar,const(char)[])
What got me was that algorithm.d(2149) turns out to be:
2147: R find(alias pred = "a == b", R, E)(R haystack, E needle)
2148: if (isInputRange!R &&
2149: is(typeof(binaryFun!pred(haystack.front, needle)) : bool))
However, this only seems to generate a bug in certain compile-time contexts. For example, enum bug = replace(int.stringof,"int","real"); compiles, while:
import std.typetuple;
mixin( "alias TypeTuple!("~replace(int.stringof,"int","real")~") This2Algebraic;");
doesn't.
Although I don't know how/why find is called.
Comment #3 by sandford — 2011-02-03T14:58:35Z
As identified by [email protected], this appears to be identical to Issue 5373 - Regression (2.051) CTFE and std.string.replace() causes "Bad binary function q{a == b}...
*** This issue has been marked as a duplicate of issue 5373 ***