Bug 12666 – @nogc std.array.front, popFront, and more
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-04-27T19:16:00Z
Last change time
2017-07-19T17:43:09Z
Keywords
pull, rejects-valid
Assigned to
nobody
Creator
bearophile_hugs
Comments
Comment #0 by bearophile_hugs — 2014-04-27T19:16:25Z
import std.algorithm: map;
immutable data = [1];
void main() @nogc {
foreach (w; data.map!((x) @nogc pure nothrow => x)) {}
}
test.d(4,5): Error: @nogc function 'D main' cannot call non-@nogc function 'test.main.MapResult!(__lambda1, immutable(int)[]).MapResult.popFront'
test.d(4,5): Error: @nogc function 'D main' cannot call non-@nogc function 'test.main.MapResult!(__lambda1, immutable(int)[]).MapResult.front'
Taking a better look the problem seems to be in std.array.front (and popFront):
@property ref T front(T)(T[] a) @safe pure nothrow
if (!isNarrowString!(T[]) && !is(T[] == void[]))
{
assert(a.length, "Attempting to fetch the front of an empty array of " ~ T.stringof);
return a[0];
}
void main() @nogc {
auto data = [1];
data.front;
}
A possible solution:
import std.traits: isNarrowString;
@property ref T front(T)(T[] a) @safe pure nothrow
if (!isNarrowString!(T[]) && !is(T[] == void[]))
{
enum msg = "Attempting to fetch the front of an empty array of " ~ T.stringof;
assert(a.length, msg);
return a[0];
}
void main() @nogc {
auto data = [1];
data.front;
}
A small disadvantage of this solution is that the error message is now computed statically, increasing binary size. But those array functions are too much important, otherwise lot of other ranges can't work in @nogc code.
Comment #1 by bearophile_hugs — 2014-04-27T19:32:55Z
(In reply to bearophile_hugs from comment #0)
> enum msg = "Attempting to fetch the front of an empty array of " ~
> T.stringof;
> assert(a.length, msg);
A little shorter code, that requires less changes:
assert(a.length, ctEval!("Attempting to fetch the front of an empty array of " ~ T.stringof));
Where ctEval is a very small construct that should be added to Phobos that forces the evaluation of an expression at compile-time.
Comment #2 by yebblies — 2014-05-12T16:07:27Z
I suspect the error message is already being computed statically thanks to constfolding, it just happens after @nogc inference has been run.