Bug 23901 – Spurious "Cannot move object [...] with internal pointer"

Status
NEW
Severity
regression
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
Linux
Creation time
2023-05-06T21:38:03Z
Last change time
2024-12-13T19:28:40Z
Keywords
wrong-code
Assigned to
No Owner
Creator
Vladimir Panteleev
Moved to GitHub: dmd#18166 →

Comments

Comment #0 by dlang-bugzilla — 2023-05-06T21:38:03Z
The error in the test case below emitted by Phobos. However, I suspect that it is a DMD code generation bug, because: 1. It disappeared when something in the DMD backend changed; 2. It does not manifest with LDC. Poorly reduced test case: ////////////////////////////////// test.d ///////////////////////////////// public import std.algorithm.mutation : move; import std.functional : forward; auto functor3(int* state) { struct Functor { int* state; this(int* i) { } } forward!state; return Functor(); } auto functor4(alias fun, State...)(State state) { struct Functor { State state; this(State state) { this.state = state; } auto opCall() { return state[0]; } } return Functor(state); } auto functor5(State)(State ) { struct Functor { this(State); auto opCall() { } } return Functor(); } auto functor6(alias fun, State...)(State state) { struct Functor { State state; this(State state) { this.state = state; } auto opCall() { fun(state); } } return Functor(state); } auto functor7(alias fun, State...)(State state) { struct Functor { State state; this(State state) { this.state = state; } auto opCall() { fun(state); } } return Functor(state); } auto functor8(alias fun, State)(State ) { struct Functor { } return Functor(); } auto functor9(alias fun, State)(State state) { return state; } auto functor10(State)(State state) { struct Functor { State state; this(State state) { this.state = move(state); } } return Functor(state); } auto valueFunctor1(Value)(Value value) { return functor4!(v => v)(value); } auto valueFunctor2(Value)(Value value) { return functor5(value); } auto select1(Cond, T, F)(Cond cond, T t, F f) { static fun(Cond cond, T t, F f) { cond() ? t() : f; } return functor6!fun(cond, t, f); } auto select2(Cond)(Cond cond) { return cond; } auto tuple(Values...)(Values values) { struct Tuple { Values values; } return Tuple(values); } auto tupleMap1(alias pred, Values...)(Values values) { return tuple(values); } auto formattingFunctor1(T)(T values) { return functor10(forward!values); } auto stringifiable1(F)(F functor) { struct Stringifiable { F functor; void toString() { functor(); } } return Stringifiable(functor); } auto fmtIf1(Cond, T, F)(Cond cond, T t, F f) { static fun(X, Sink...)(X x) { x().formattingFunctor1; } return select1( cond.valueFunctor1, functor7!fun(t), functor8!fun(f), ).stringifiable1; } auto fmtIf2(Cond, T, F)(Cond cond, T t, F f) { static fun() { } return select2( cond.valueFunctor2, ); } auto fmtSeq1(Values...)(Values values) { return values .tupleMap1!(value=> fmt); } int i; struct Wand { @property endl() { return functor3(&i); } } void main() { Wand wand; auto v = fmtIf1(true, () => fmtSeq1( fmtIf2(true, "", "", ), wand.endl, ), "", ) ; v.toString(); } /////////////////////////////////////////////////////////////////////////// Introduced in https://github.com/dlang/dmd/pull/9434
Comment #1 by dlang-bugzilla — 2023-05-06T21:40:07Z
> The error in the test case below emitted by Phobos. is emitted* > 1. It disappeared when something in the DMD backend changed; appeared*
Comment #2 by maxhaton — 2023-05-06T23:32:55Z
What is the error supposed to be? I can't reproduce this with dmd on macos for example
Comment #3 by dlang-bugzilla — 2023-05-07T06:49:29Z
It's in the issue title. On 2.103.1, the full output is: core.exception.AssertError@/home/vladimir/data/software/dmd/dmd.2.103.1.linux/dmd2/linux/bin64/../../src/phobos/std/algorithm/mutation.d(1427): Cannot move object of type Tuple with internal pointer unless `opPostMove` is defined. ---------------- ??:? _d_assert_msg [0x55972b30555c] ??:? pure nothrow @nogc @safe void std.algorithm.mutation.moveEmplaceImpl!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).moveEmplaceImpl(scope ref test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple, return scope ref test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fddb0] ??:? pure nothrow @nogc @trusted test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple std.algorithm.mutation.trustedMoveImpl!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).trustedMoveImpl(return scope ref test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fdf7f] ??:? pure nothrow @nogc @safe test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple std.algorithm.mutation.moveImpl!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).moveImpl(return scope ref test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fdd60] ??:? pure nothrow @nogc @safe test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple std.algorithm.mutation.move!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).move(return scope ref test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fdd54] ??:? pure nothrow ref @nogc @safe test.functor10!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).functor10(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).Functor test.functor10!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).functor10(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).Functor.__ctor(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fdd44] ??:? pure nothrow @nogc @safe test.functor10!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).functor10(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).Functor test.functor10!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).functor10(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fdd2d] ??:? pure nothrow @nogc @safe test.functor10!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).functor10(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).Functor test.formattingFunctor1!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple).formattingFunctor1(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple) [0x55972b2fdc17] ??:? nothrow @nogc @safe void test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fun!(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).fun(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe) [0x55972b2fdbe0] ??:? nothrow @nogc @safe void test.functor7!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fun, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).functor7(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).Functor.opCall() [0x55972b2fdba2] ??:? nothrow @nogc @safe void test.select1!(test.functor4!(test.valueFunctor1!(bool).valueFunctor1(bool).__lambda2, bool).functor4(bool).Functor, test.functor7!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fun, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).functor7(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).Functor, test.functor8!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @n... ??:? nothrow @nogc @safe void test.functor6!(test.select1!(test.functor4!(test.valueFunctor1!(bool).valueFunctor1(bool).__lambda2, bool).functor4(bool).Functor, test.functor7!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fun, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).functor7(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).Functor, test.functor8!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delega... ??:? nothrow @nogc @safe void test.stringifiable1!(test.functor6!(test.select1!(test.functor4!(test.valueFunctor1!(bool).valueFunctor1(bool).__lambda2, bool).functor4(bool).Functor, test.functor7!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fun, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).functor7(test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe).Functor, test.functor8!(test.fmtIf1!(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).Tuple delegate() nothrow @nogc @safe, immutable(char)[]).fmtIf1(bool, test.tuple!(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).Functor).tuple(test.functor5!(bool).functor5(bool).Functor, test.functor3(int*).... ??:? _Dmain [0x55972b2fd7cc]
Comment #4 by maxhaton — 2023-05-07T21:57:48Z
The (full) message isn't in the issue title.
Comment #5 by maxhaton — 2023-05-07T22:01:24Z
Once again with a .1 release, I cannot reproduce. // TODO: this assert pulls in half of phobos. we need to work out an alternative assert strategy. // static if (!is(T == class) && hasAliasing!T) if (!__ctfe) // { // import std.exception : doesPointTo; // assert(!doesPointTo(source, source) && !hasElaborateMove!T), // "Cannot move object with internal pointer unless `opPostMove` is defined."); // } From lifetime.d, are you on an old druntime or something? (This has been commented out for apparently 4 years).
Comment #6 by dlang-bugzilla — 2023-05-07T22:13:37Z
Please pay attention to the public import std.algorithm.mutation : move; line. Yes, it doesn't happen with the core.lifetime implementation. But, again, I don't think the problem is in Phobos or Druntime, it seems to be in the compiler. And yeah, since it's deep in the backend, it might not be reproducible on other platforms. I haven't reduced it further because it's easy to work around (use the core.lifetime implementation) but there is still probably a bug in the backend.
Comment #7 by dlang-bugzilla — 2023-05-07T22:22:19Z
(In reply to mhh from comment #5) > > Once again with a .1 release, I cannot reproduce. If you're still having trouble reproducing it, it does reproduce on run.dlang.io.
Comment #8 by maxhaton — 2023-05-07T23:07:04Z
It seems to only reproduce with rdmd
Comment #9 by maxhaton — 2023-05-07T23:08:27Z
^^ ignore that
Comment #10 by maxhaton — 2023-05-07T23:15:27Z
I actually can reproduce with ldc2 on my M1 macbook
Comment #11 by dlang-bugzilla — 2023-05-07T23:22:17Z
(In reply to mhh from comment #10) > I actually can reproduce with ldc2 on my M1 macbook That's interesting, maybe there is more than one bug here.
Comment #12 by robert.schadek — 2024-12-13T19:28:40Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18166 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB