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
Comment #1 by acehreli — 2016-10-11T19:16:05Z
Comment #2 by ketmar — 2016-10-13T20:12:28Z
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
Comment #4 by ketmar — 2016-10-13T21:16:13Z
yeah, another known bug: #11720
Comment #5 by ketmar — 2016-10-13T21:16:50Z
yay, i can never remember what kind of numbers will be turned to links here: https://issues.dlang.org/show_bug.cgi?id=11720
Comment #6 by mathias.lang — 2016-10-22T16:38:49Z
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 ***