/* REQUIRED_ARGS: -preview=nosharedaccess TEST_OUTPUT: --- pure nothrow @nogc ref @safe shared(C1)(return ref shared(C1) c) pure nothrow @nogc ref @safe shared(int)(return ref shared(C3) c) --- */ ref shared(int) f(return shared ref int y) { return y; } // https://issues.dlang.org/show_bug.cgi?id=20908 void test20908() { // shared locals (or struct members) should be able to be initialised: shared int x; ref shared(int) fun() { static shared(int) val; // return by reference return val; } ref shared(int) fun2() { static shared(int)* val; // transfer pointer to reference return *val; } ref shared(int) fun3() { static shared(int)*** val; // Multiple indirections return ***val; } } // Simple tests for `DotVarExp` // A `DotVarExp` is `a.b`. If `a` is a `shared ref`, // it is of type `shared(T)*` (as opposed to `shared(T*)`). // We should allow arbitrarily nested `DotVarExp` as long // as no shared memory is read, as in the case above // (we're just offsetting a pointer). struct C1 { int value; } struct C2 { C1 c1; } struct C3 { C2 c1; C2 c2; } ref shared(int) test_dotvarexp_1(return ref shared C1 c) { return c.value; } shared(int)* test_dotvarexp_2(return ref shared C1 c) { return &c.value; } shared(C2)* test_dotvarexp_3(return ref shared C3 c) { return &c.c1; } shared(C2)* test_dotvarexp_4(return ref shared C3 c) { return &c.c2; } ref shared(int) test_dotvarexp_5(return shared ref C3 c) { return c.c1.c1.value; } ref shared(int) test_dotvarexp_5(return ref shared(C3)[] c) { return c[0].c1.c1.value; } // Test `auto` inference auto ref test_inference_1(return ref shared C1 c) { return c; } pragma(msg, typeof(test_inference_1)); auto ref test_inference_2(return ref shared C3 c) { return c.c2.c1.value; } pragma(msg, typeof(test_inference_2)); // https://issues.dlang.org/show_bug.cgi?id=21793 struct Child { this(int) shared {} } struct Parent { shared Child ch; this(int i) shared { ch = shared Child(i); } }