Bug 5406 – [patch] Major regressions in std.algorithm for functions relying on is(typeof(binaryFun!... due to a static assert in binaryFunImpl

Status
RESOLVED
Resolution
DUPLICATE
Severity
regression
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
Other
OS
Windows
Creation time
2011-01-03T21:18:00Z
Last change time
2011-02-03T14:58:35Z
Keywords
patch
Assigned to
nobody
Creator
sandford
See also
http://d.puremagic.com/issues/show_bug.cgi?id=5373

Comments

Comment #0 by sandford — 2011-01-03T21:18:21Z
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 ***