May 01 [Issue 24531] New: foreach lowering fails to compile with dip1000 and std.array.array | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=24531 Issue ID: 24531 Summary: foreach lowering fails to compile with dip1000 and std.array.array Product: D Version: D2 Hardware: x86_64 OS: Linux Status: NEW Severity: major Priority: P1 Component: dmd Assignee: nobody@puremagic.com Reporter: atila.neves@gmail.com The code below fails to compile. This is the minimum reduction I could find. The `arrayCtfe` function is the static if branch in std.array.array for __ctfe. This particular example can be fixed with an alternative implementation that calls the range API directly like so: ------ while(!range.empty) { result ~= range.front; range.popFront; } return result; ------ Unfortunately trying to do this in std.array results in compilation failures for other ranges, and checking that this implementation is valid for the range in question with `is(typeof)` or `__traits(compiles)` crashes the compiler. Offending code: ----- struct Target { string[] strings() @safe pure return scope const { return []; } } auto maybeAddDependencies(in Target target, in string projectPath) @safe pure { Target[] targets; scope srcs = targets.filter!(a => true); return srcs .map!(t => t.strings[0]) .arrayCtfe ; } // this is the implementation in std.array.array guarded by `if(__ctfe)` auto arrayCtfe(R)(auto ref R range) { import std.traits: ForeachType; ForeachType!R[] result; // string[] foreach (ref e; range) { result ~= e; } return result; } ----- -- |
Copyright © 1999-2021 by the D Language Foundation