dmd/compiler/test/runnable/rvalue1.d
2025-01-10 11:19:29 -08:00

260 lines
4.6 KiB
D

/* PERMUTE_ARGS: -preview=rvaluerefparam
/* testing __rvalue */
import core.stdc.stdio;
/********************************/
int foo(int) { printf("foo(int)\n"); return 1; }
int foo(ref int) { printf("foo(ref int)\n"); return 2; }
void test1()
{
int s;
assert(foo(s) == 2);
assert(foo(__rvalue(s)) == 1);
}
/********************************/
struct S
{
nothrow:
~this() { printf("~this() %p\n", &this); }
this(ref S) { printf("this(ref S)\n"); }
void opAssign(S) { printf("opAssign(S)\n"); }
}
void test2()
{
S s;
S t;
t = __rvalue(s);
}
/********************************/
struct S3
{
int a, b, c;
this(S3) {}
this(ref S3) {}
}
void test3()
{
S3 s;
S3 x = s; // this line causes the compiler to crash
}
/********************************/
struct S4
{
void* p;
this(ref S4) { }
this(S4 s)
{
assert(&s is &x); // confirm the rvalue reference
}
}
__gshared S4 x;
void test4()
{
S4 t = __rvalue(x);
}
/********************************/
struct S5
{
this(S5 s) { printf("this(S5 s)\n"); }
this(ref inout S5 s) inout { printf("this(ref inout S5 s) inout\n"); }
}
void test5()
{
S5 t;
S5 t1 = t;
S5 t2 = __rvalue(t);
}
/********************************/
int moveCtor, copyCtor, moveAss, copyAss;
struct S6
{
this(S6 s) { ++moveCtor; }
this(ref S6 s) { ++copyCtor; }
void opAssign(S6 s) { ++moveAss; }
void opAssign(ref S6 s) { ++copyAss; }
}
void test6()
{
S6 x;
S6 s = x;
// printf("S6 s = x; moveCtor %d copyCtor %d moveAss %d copyAss %d\n", moveCtor, copyCtor, moveAss, copyAss);
assert(copyCtor == 1);
S6 s2 = __rvalue(x);
// printf("S6 s2 = __rvalue(x); moveCtor %d copyCtor %d moveAss %d copyAss %d\n", moveCtor, copyCtor, moveAss, copyAss);
assert(moveCtor == 1);
s2 = s;
// printf("s2 = s; moveCtor %d copyCtor %d moveAss %d copyAss %d\n", moveCtor, copyCtor, moveAss, copyAss);
assert(copyAss == 1);
s2 = __rvalue(s);
// printf("s2 = __rvalue(s); moveCtor %d copyCtor %d moveAss %d copyAss %d\n", moveCtor, copyCtor, moveAss, copyAss);
assert(moveAss == 1);
assert(copyCtor == 1 && moveCtor == 1 && copyAss == 1 && moveAss == 1);
}
/********************************/
// https://github.com/dlang/dmd/pull/17050#issuecomment-2543370370
struct MutableString(size_t E) {}
struct StringTest
{
alias toString this;
const(char)[] toString() const pure
=> null;
this(StringTest rhs) {}
this(ref inout StringTest rhs) inout pure {}
this(typeof(null)) inout pure {}
this(size_t Embed)(MutableString!Embed str) inout {}
~this() {}
}
void test7()
{
StringTest s = StringTest(null);
}
/********************************/
// https://github.com/dlang/dmd/issues/20562
struct S8
{
int a,b;
this(S8) { printf("this(S)\n"); b = 4; }
this(ref S8) { printf("this(ref S)\n"); assert(0); }
}
S8 returnRval(ref S8 arg)
{
static if (0)
{
/* __copytmp2 = 0 ;
_D7rvalue51S6__ctorMFNcKSQxQrZQg call (arg param #__copytmp2);
* __HID1 streq 1 __copytmp2;
__HID1;
*/
return arg;
}
else static if (1)
{
/* * __HID1 streq 1 * arg;
__HID1;
*/
return __rvalue(arg); // should move-construct the NRVO value
}
else
{
/* * t = 0 ;
t;
_TMP0 = t;
_D7rvalue51S6__ctorMFNcSQwQqZQg call (arg param _TMP0);
t;
*/
S8 t = __rvalue(arg);
return t;
}
}
void test8()
{
S8 s;
S8 t = returnRval(s);
printf("t.b: %d\n", t.b);
assert(t.b == 4);
}
/********************************/
struct T9
{
int i;
inout this(ref inout T9 t) { this.i = t.i - 1; printf("this(ref T9)\n"); }
inout this(inout T9 t) { this.i = t.i + 1; printf("this(T9)\n"); }
}
struct S9
{
T9 t;
//inout this(return ref scope inout S9 t);// { this.i = t.i - 1; printf("this(ref T9)\n"); }
//@system inout this(return scope inout S9 t);// { this.i = t.i + 1; printf("this(T9)\n"); }
}
void test9()
{
S9 s;
s.t.i = 3;
S9 u = s;
printf("u.t.i = %d\n", u.t.i);
assert(u.t.i == 2);
S9 v = __rvalue(u);
printf("v.t.i = %d\n", v.t.i);
assert(v.t.i == 3);
}
/********************************/
// https://github.com/s-ludwig/taggedalgebraic/issues/75
struct T10
{
string s;
this(T10) {}
this(string v) { s = v; }
}
struct S10
{
T10 p;
}
void test10()
{
S10 s = S10(T10("hello"));
assert(s.p.s == "hello");
}
/********************************/
int main()
{
test1();
test2();
test3();
test4();
test5();
test6();
test7();
test8();
test9();
return 0;
}