Bug 16608 – 'static foreach', nested function template, 'static if', anySatisfy: Only the first iteration seems to work
Status
RESOLVED
Resolution
DUPLICATE
Severity
normal
Priority
P3
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-10-11T19:10:00Z
Last change time
2016-10-22T16:41:26Z
Assigned to
nobody
Creator
acehreli
Comments
Comment #0 by acehreli — 2016-10-11T19:10:27Z
import std.meta;
void main() {
foreach (s; AliasSeq!("a", "b")) {
// The problem is that this function is called only for the "a" iteration
bool condition(string x)() {
pragma(msg, "comparing ", x, " and ", s);
return x == s;
}
// This condition is expected to be true for the "b" iteration
static if (anySatisfy!(condition, AliasSeq!("b"))) {
pragma(msg, "yes for ", s);
}
else {
pragma(msg, "NO for ", s);
}
}
}
However, the condition() is called only for "a" and we get "NO" for the "b" iteration as well:
comparing b and a
NO for a
NO for b <-- Why didn't we get "comparing b and b" before this?
Ali
yeah, semi-known thing for static foreach: sometimes it is failing to instantiate 2nd and more template instances. actually, not really failing, but cannot see that templates for different iterations are really different, and merging 'em into one.
afair, here frontend sees a template whose signature (mangled name, actually) doesn't change between iterations, and deciding that one will be enough. ;-)
this is hard to fix without introducing some (noticable) slowdown (or, maybe, proper `static foreach` operator).
for now, force instantiation with alias seems to be the only solution (this is for those people who interested in workaround until this issue is somehow fixed):
alias cc = condition!s;
... anySatisfy!(cc, AliasSeq!("b")) ...
Comment #3 by acehreli — 2016-10-13T21:01:54Z
Thanks.
I forgot to add another thing that Johan had discovered: I don't know whether this is an implementation issue but if static foreach can be seen as an expansion of the loop body as separate scopes then the following case seems to be related to this bug.
There can't be two nested functions even if they are in different scopes:
void main() {
{
void foo(){}
}
{
void foo(){} // <-- Error
}
}
Error: declaration foo is already defined in another scope in main
Yeah, sadly this is a known (and old bug), one of the worst IMO.
The meta bug that Kenji opened to solve this is https://issues.dlang.org/show_bug.cgi?id=14831
*** This issue has been marked as a duplicate of issue 14381 ***
Comment #7 by dlang-bugzilla — 2016-10-22T16:41:26Z
*** This issue has been marked as a duplicate of issue 14831 ***