Bug 11864 – std.variant.Variant doesn't work with CTFE

Status
NEW
Severity
enhancement
Priority
P4
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-01-03T14:45:12Z
Last change time
2024-12-01T16:19:50Z
Assigned to
No Owner
Creator
Dylan Knutson
Moved to GitHub: phobos#10026 →

Comments

Comment #0 by tcdknutson — 2014-01-03T14:45:12Z
e.g. --- import std.variant : Variant; Variant makeVariant(T)(T value) { return Variant(value); } void main() { const a = makeVariant("bar"); pragma(msg, a); } --- Results in: /opt/compilers/dmd2/include/std/variant.d(547): Error: memcpy cannot be interpreted at compile time, because it has no available source code /opt/compilers/dmd2/include/std/variant.d(512): called from here: this.opAssign(value) /d214/f186.d(6): called from here: (VariantN!(32LU) __ctmp1402 = VariantN; , __ctmp1402).this(value) /d214/f186.d(11): called from here: makeVariant("bar") /d214/f186.d(12): while evaluating a.init /d214/f186.d(12): while evaluating pragma(msg, a) Note that the error doesn't happen if pragma(msg, a) is removed. I guess the compiler is lazily evaluating 'a'?
Comment #1 by clugdbug — 2014-01-14T03:29:27Z
> Note that the error doesn't happen if pragma(msg, a) is removed. I guess the compiler is lazily evaluating 'a'? No, 'a' is normally just a run-time value. By putting it in a pragma(msg), you're asking the compiler to evaluate it at compile time. This fails because Variant uses memcpy. This isn't a bug. Replacing the memcpy with an array slice assignment would just cause it to fail in a different way. Variants are intrinsically a bit nasty, they're basically a union, so there's actually multiple reasons why they don't work in CTFE.
Comment #2 by norm.rowtree — 2019-02-07T07:55:06Z
I get pretty much the same error reported using the code snippet below and DMD D Compiler v2.084.0 struct S { Variant v = Variant(10); } void main() {auto s = S();} dmd2/linux/bin64/../../src/phobos/std/variant.d(661): Error: memcpy cannot be interpreted at compile time, because it has no available source code Error: cannot interpret <error> at compile time I don't need this evaluated at compile time, I just want a default value when the struct is instantiated at runtime. Thanks, Norm
Comment #3 by dfj1esp02 — 2019-02-08T22:07:19Z
Default struct value doesn't run code at runtime and there are no plans for it. You can disable default struct constructor to make non-default constructor mandatory, `S()` form is fine too if you declare static opCall.
Comment #4 by ali.akhtarzada — 2019-03-23T09:45:25Z
This is unfortunately a pain point in the language. The problem is that D expects a .init value for every type to be known. So currently, the (arbitrary) choice has been to not allow a default constructor because people could get confused by statements such as struct A { int i; this() { i = 4; } } A a; writeln(a.i); // prints 0 The code above, in D, needs to call A.init, which is not the same as the constructor. The only work around is the static opCall, but then you can't have any constructors, which is unfortunately not practical. D could either allow a default constructor and document the differences between initialization and construction, or lift the restriction of static opCall and other constructors in the same type.
Comment #5 by norm.rowtree — 2019-04-15T21:46:53Z
Thanks, the static opCall workaround is good enough for my needs.
Comment #6 by snarwin+bugzilla — 2020-06-13T19:34:16Z
*** Issue 17987 has been marked as a duplicate of this issue. ***
Comment #7 by robert.schadek — 2024-12-01T16:19:50Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/phobos/issues/10026 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB