I think there really is some bug here. I tried to use your template helper function, and it seems the order in which I put two constraints in a template signature changes the way dmd compiles the code. Consider this:<br><br>
import std.stdio;<br><br>void main()<br>{<br>}<br><br>template areComparable(T1, T2)<br>{<br>   enum bool areComparable = is(typeof(T1.init == T2.init)); // eponymous template trick<br>}<br><br>T[] find(T, E)(T[] haystack, E needle)<br>
    if (is(typeof(haystack[0] != needle) == bool) &amp;&amp;<br>    areComparable!(T, E))<br>{<br>    while (haystack.length &gt; 0 &amp;&amp; haystack[0] != needle) {<br>        haystack = haystack[1 .. $];<br>    }<br>    return haystack;<br>
}<br><br>T1[] find(T1, T2)(T1[] longer, T2[] shorter)<br>    if (is(typeof(longer[0 .. 1] == shorter) : bool) &amp;&amp; (areComparable!(T1, T2)))<br>    <br>{<br>    while (longer.length &gt;= shorter.length) {<br>        if (longer[0 .. shorter.length] == shorter)<br>
            break;<br>        longer = longer[1 .. $];<br>    }<br>    return longer;<br>}<br><br>unittest {<br>    double[] d = [1.5, 2.4];<br>    assert(find(d, 1.0) == null);<br>    assert(find(d, 1.5) == d);<br>    string[] s = [&quot;one&quot;, &quot;two&quot;];<br>
    assert(find(s, &quot;two&quot;) == [&quot;two&quot;]);<br>}<br><br>This will give out the error &quot;incompatible types for comparing of string and immutable(char)&quot;. But if I reverse the order of the constraints in the second template, like so:<br>
<br>import std.stdio;<br><br>void main()<br>{<br>}<br><br>template areComparable(T1, T2)<br>{<br>   enum bool areComparable = is(typeof(T1.init == T2.init)); // eponymous template trick<br>}<br><br>T[] find(T, E)(T[] haystack, E needle)<br>
    if (is(typeof(haystack[0] != needle) == bool) &amp;&amp;<br>    areComparable!(T, E))<br>{<br>    while (haystack.length &gt; 0 &amp;&amp; haystack[0] != needle) {<br>        haystack = haystack[1 .. $];<br>    }<br>    return haystack;<br>
}<br><br><br>T1[] find(T1, T2)(T1[] longer, T2[] shorter)<br>    if (areComparable!(T1, T2) &amp;&amp; is(typeof(longer[0 .. 1] == shorter) : bool))<br>{<br>    while (longer.length &gt;= shorter.length) {<br>        if (longer[0 .. shorter.length] == shorter)<br>
            break;<br>        longer = longer[1 .. $];<br>    }<br>    return longer;<br>}<br><br>unittest {<br>    double[] d = [1.5, 2.4];<br>    assert(find(d, 1.0) == null);<br>    assert(find(d, 1.5) == d);<br>    string[] s = [&quot;one&quot;, &quot;two&quot;];<br>
    assert(find(s, &quot;two&quot;) == [&quot;two&quot;]);<br>}<br><br>Then this happily compiles. All of the asserts will call the first templated function.<br><br><br><div class="gmail_quote">On Sat, Jul 31, 2010 at 12:04 AM, Philippe Sigaud <span dir="ltr">&lt;<a href="mailto:philippe.sigaud@gmail.com">philippe.sigaud@gmail.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;"><div>First,  trying a copy-paste of your code gives me an error in object.di</div><div>(DMD 2.047 on Windows)</div>
<div><br></div><div>C:\dmd\windows\bin\..\..\src\druntime\import\object.di|487|Error: incompatible types for ((a) != (a2[i])): &#39;string&#39; and &#39;immutable(char)&#39;|</div>
<div>||=== Build finished: 1 errors, 0 warnings ===|</div><div><br></div><div>And Code::Blocks jumps me to object.di:</div><div><br></div><div>bool _ArrayEq(T1, T2)(T1[] a1, T2[] a2)</div><div>{</div><div>    if (a1.length != a2.length)</div>

<div><span style="white-space: pre-wrap;">        </span>return false;</div><div>    foreach(i, a; a1)</div><div>    {<span style="white-space: pre-wrap;">        </span>if (a != a2[i]) // &lt;-- line 487. Uh oh, trying to compare strings and chars</div>

<div><span style="white-space: pre-wrap;">        </span>    return false;</div><div>    }</div><div>    return true;</div><div>}</div><div><br></div><div>I had to modify it:</div><div><br></div><div>bool _ArrayEq(T1, T2)(T1[] a1, T2[] a2) </div>

<div><span style="white-space: pre-wrap;">        </span>if (is(typeof(T1.init != T2.init))) // Are T1 and T2 comparable? If not, do not bother to compile</div><div>{</div><div>   if (a1.length != a2.length) return false;</div>

<div>    foreach(i, a; a1)</div><div>    {<span style="white-space: pre-wrap;">        </span>if (a != a2[i])</div><div>        return false;</div><div>    }</div><div>    return true;</div><div>}</div><div><br></div>
<div>Another possibility would have it return false, but in that case, array comparisons always compile and we lose the ability to use them as test for instantiating a template.</div><div><br></div><div>I guess _ArrayEq is some internal called by the constraint, while doing the comparison. Saving object.di and recompiling everything allows the templates constraints to function and gives me a call to the first find.</div>

<div><br></div><div>Without the &#39;&amp;&amp; false&#39;, it still calls the first find... because it still cannot instantiate the second template:</div><div><br></div><div>The first find can be instantiated with T = immutable(char)[] and E = immutable(char)[], there is nothing stopping it: T and E are the same type, so they are trivially comparable. &quot;two&quot; is a valid target value for [&quot;one&quot;, &quot;two&quot;].</div>

<div>The second find would have T1 = immutable(char)[] and T2 = immutable(char) and those do not compare.</div><div><br></div><div><br></div><div>testing it, find(&quot;one two three&quot;, &quot;two&quot;) correctly calls the second version and returns &quot;two three&quot;.</div>

<div><br></div><div>So, maybe you just found a bug in object.di._ArrayEq. I&#39;ll post on the main list. Anyway, for me, it seems to work, if I understand correctly what you&#39;re doing.</div><div><br></div><div>Btw, if you find yourself using the same constraint regularly, you can abstract it away in another template that returns (er, becomes, rather) a boolean:</div>

<div><br></div><div>template areComparable(T1, T2)</div><div>{</div><div>   enum bool areComparable = is(typeof(T1.init == T2.init)); // eponymous template trick</div><div>}</div><div><br></div><div>And then:</div><div><br>

</div><div><span style="font-family: arial,sans-serif; font-size: 12.5px; border-collapse: collapse;"><div style="color: rgb(80, 0, 80);"><div class="im">T[] find(T, E)(T[] haystack, E needle)<br></div>    if (areComparable!(T, E))<br>

</div><div style="color: rgb(80, 0, 80);">{<br>}<br><br><br></div><div style="color: rgb(80, 0, 80);">T[] find(T, E)(T[] longer, E[] shorter)<br></div>    if (areComparable!(T, E))<div style="color: rgb(80, 0, 80);">
<br>{<br>}<br></div><div style="color: rgb(80, 0, 80);"><br></div><div style="color: rgb(80, 0, 80);">Which makes for cleaner code. I renamed T1 and T2 to T and E, so showcase the difference between the two.</div>
<div style="color: rgb(80, 0, 80);"><br></div><div style="color: rgb(80, 0, 80);"><br></div><div style="color: rgb(80, 0, 80);"><span style="font-size: 12.5px;">Philippe</span></div>
<div style="color: rgb(80, 0, 80);"><br></div></span></div>
</blockquote></div><br>