Bug 7964 – std.algorithm.swap is not CTFE-compatible for structs with non-trivial assignment

Status
RESOLVED
Resolution
WORKSFORME
Severity
normal
Priority
P2
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2012-04-21T22:24:53Z
Last change time
2019-12-14T09:42:03Z
Keywords
bootcamp
Assigned to
No Owner
Creator
Caligo

Comments

Comment #0 by iteronvexor — 2012-04-21T22:24:53Z
Location: Earth Temperature: 64°F Wind: SE at 5 mph Humidity: 45% DMD 2.059, 64-bit GNU/Linux ----------------------------------->8----------------------------------->8----------------------------------- import std.typecons : Tuple; import std.array : appender; import std.algorithm : sort; import std.stdio : writeln; alias double Real; struct S { Tuple!(Real, Real)[] _data; alias _data this; } private auto gen(K, V)(V[K] data) { alias Tuple!(K, V) T; T[] app; foreach(k, v; data) app ~= T(k,v); sort(app); return app; } auto s(Real[Real] data) { return S(gen!(Real, Real)(data)); } S bug = s([360.0:0.000000122200, 361.0:0.000000185138, 362.0:0.000000278830, 363.0:0.000000417470, 364.0:0.000000621330, 365.0:0.000000919270, 366.0:0.000001351980, 367.0:0.000001976540, 368.0:0.000002872500, 369.0:0.000004149500, 370.0:0.000005958600, 371.0:0.000008505600, 372.0:0.000012068600, 373.0:0.000017022600, 374.0:0.000023868000, 375.0:0.000033266000, 376.0:0.000046087000, 377.0:0.000063472000, 378.0:0.000086892000, 379.0:0.000118246000, 380.0:0.000159952000, 381.0:0.000215080000, 382.0:0.000287490000, 383.0:0.000381990000, 384.0:0.000504550000, 385.0:0.00066244]); void main() { } -----------------------------------8<-----------------------------------8<----------------------------------- compiling the above gives: /usr/include/x86_64-linux-gnu/dmd/phobos/std/algorithm.d(1498): Error: reinterpreting cast from Tuple!(double,double)* to ubyte* is not supported in CTFE /usr/include/x86_64-linux-gnu/dmd/phobos/std/algorithm.d(7018): called from here: swap(r[i1],r[i2]) /usr/include/x86_64-linux-gnu/dmd/phobos/std/algorithm.d(7047): called from here: swapAt(r,pivotIdx,r.length - 1LU) /usr/include/x86_64-linux-gnu/dmd/phobos/std/algorithm.d(6787): called from here: sortImpl(r) t1.d(19): called from here: sort(app) t1.d(24): called from here: gen(data) t1.d(28): called from here: s([360:1.222e-07,361:1.85138e-07,362:0x9.5b21a78330de599p-25,363:0xe.020a3d0e070d933p-25,364:0xa.6c978f4795f4a92p-24,365:9.1927e-07,366:1.35198e-06,367:1.97654e-06,368:2.8725e-06,369:0x8.b3beeffb8c391a1p-21,370:0xc.7effbf874cb77f1p-21,371:8.5056e-06,372:0xc.a7a3e07ee23183ap-20,373:1.70226e-05,374:2.3868e-05,375:3.3266e-05,376:4.6087e-05,377:6.3472e-05,378:8.6892e-05,379:0xf.7fad67e041a747ep-17,380:0.000159952,381:0.00021508,382:0.00028749,383:0xc.845d4758da0bcfap-15,384:0x8.443c6ff2d722913p-14,385:0.00066244]) Shortening the associative array by just one works. That is to say: ... S bug = s([360.0:0.000000122200, 361.0:0.000000185138, 362.0:0.000000278830, 363.0:0.000000417470, 364.0:0.000000621330, 365.0:0.000000919270, 366.0:0.000001351980, 367.0:0.000001976540, 368.0:0.000002872500, 369.0:0.000004149500, 370.0:0.000005958600, 371.0:0.000008505600, 372.0:0.000012068600, 373.0:0.000017022600, 374.0:0.000023868000, 375.0:0.000033266000, 376.0:0.000046087000, 377.0:0.000063472000, 378.0:0.000086892000, 379.0:0.000118246000, 380.0:0.000159952000, 381.0:0.000215080000, 382.0:0.000287490000, 383.0:0.000381990000, 384.0:0.000504550000]); ... does not trigger the bug. Also, commenting out 'sort(app)' does not trigger the bug. This is as organic as it gets.
Comment #1 by clugdbug — 2012-04-23T22:18:06Z
I don't know what you mean by "organic". The code works for arrays which are small enough that sort() uses insertion sort, but when sort() switches to quicksort, it does an unsafe cast that CTFE doesn't support.
Comment #2 by clugdbug — 2012-05-21T00:49:58Z
Changing to a Phobos bug because the error message is perfectly clear; there's no compiler bug here, and nothing strange going on. Priority reduced from critical to normal. CTFE is complaining because std.algorithm.swap is doing a nasty hack. I'm not sure if the hack is really valid for structs with postblit.
Comment #3 by timon.gehr — 2012-05-21T02:52:54Z
(In reply to comment #2) > Changing to a Phobos bug because the error message is perfectly clear; there's > no compiler bug here, and nothing strange going on. Priority reduced from > critical to normal. > > CTFE is complaining because std.algorithm.swap is doing a nasty hack. I'm not > sure if the hack is really valid for structs with postblit. Postblit has to be called when a struct is copied, but not when it is moved.