Bug 12315 – std.array.array at compile-time too

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
x86
OS
Windows
Creation time
2014-03-08T07:02:00Z
Last change time
2017-07-02T02:22:09Z
Keywords
CTFE, rejects-valid
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2014-03-08T07:02:11Z
import std.array: array; struct Foo1 { int i; } struct Foo2 { immutable int i; } void main() { enum r1 = [Foo1(1)].array; // OK enum r2 = [Foo2(1)].array; // Error } dmd 2.066alpha gives: ...\dmd2\src\phobos\std\conv.d(3908,23): Error: memcpy cannot be interpreted at compile time, because it has no available source code ...\dmd2\src\phobos\std\array.d(45,23): called from here: emplaceRef(result[i], e) temp.d(10,24): called from here: array([Foo2(1)])
Comment #1 by peter.alexander.au — 2014-03-09T05:00:05Z
Changing this to dmd CTFE bug. I can't think of any way to solve it in Phobos without more compiler support.
Comment #2 by bearophile_hugs — 2014-03-09T05:26:20Z
(In reply to comment #1) > Changing this to dmd CTFE bug. I can't think of any way to solve it in Phobos > without more compiler support. This seems to work: import std.traits: ForeachType; ForeachType!R[] myArray(R)(R r) { if (__ctfe) { typeof(return) result; foreach (item; r) result ~= r; return result; } else { // ... assert(0); } } struct Foo1 { int i; } struct Foo2 { immutable int i; } void main() { enum r1 = [Foo1(1)].myArray; // OK enum r2 = [Foo2(1)].myArray; // OK }
Comment #3 by peter.alexander.au — 2014-03-09T06:46:00Z
(In reply to comment #2) > (In reply to comment #1) > > Changing this to dmd CTFE bug. I can't think of any way to solve it in Phobos > > without more compiler support. > > This seems to work: ... why didn't I think of that :-) I'll make the pull.
Comment #4 by bearophile_hugs — 2014-03-09T06:59:29Z
(In reply to comment #3) > I'll make the pull. There are also assumeSafeAppend, reserve/capacity, and so on. I don't know if they speedup the code at compile-time too.
Comment #5 by peter.alexander.au — 2014-03-09T07:01:52Z
Comment #6 by bearophile_hugs — 2014-03-09T07:11:11Z
(In reply to comment #5) > There are also assumeSafeAppend, reserve/capacity, and so on. I don't know if > they speedup the code at compile-time too. It seems code like this doesn't yet work: import std.traits: ForeachType; import std.range: hasLength; ForeachType!R[] myArray(R)(R r) { if (__ctfe) { typeof(return) result; static if (hasLength!R) result.reserve = r.length; foreach (item; r) result ~= r; return result; } else { // ... assert(0); } } struct Foo1 { int i; } struct Foo2 { immutable int i; } void main() { enum r1 = [Foo1(1)].myArray; // OK enum r2 = [Foo2(1)].myArray; // OK }
Comment #7 by github-bugzilla — 2014-03-09T12:06:52Z
Commits pushed to master at https://github.com/D-Programming-Language/phobos https://github.com/D-Programming-Language/phobos/commit/8d9479c3a4b1f3cb7738b27d90d92330c8d1f058 Fix Issue 12315 - `array` at compile-time with all types Problem was that `emplaceRef` calls `memcpy` for some types, which is unsafe and unavailable at compile time. https://d.puremagic.com/issues/show_bug.cgi?id=12315 https://github.com/D-Programming-Language/phobos/commit/6b31fb8685b458f142db34ca21e5c9639e5cb38d Merge pull request #1986 from Poita/bug12315 Fix Issue 12315 - `array` at compile-time with all types
Comment #8 by monarchdodra — 2014-03-10T00:14:37Z
Reopening because I'm not sure it's worth filing something new, but `Appender` will also CTFE fail on the same types.
Comment #9 by dlang-bugzilla — 2017-07-02T02:22:09Z
(In reply to monarchdodra from comment #8) > Reopening because I'm not sure it's worth filing something new, but > `Appender` will also CTFE fail on the same types. Can't reproduce this: import std.array; struct Foo1 { int i; } struct Foo2 { immutable int i; } T[] fun(T)() { auto a = appender!(T[]); return a.data; } enum foo1 = fun!Foo1(); enum foo2 = fun!Foo2(); In any case, it should be filed as a separate bug.