1 change: 1 addition & 0 deletions compiler/src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -6428,6 +6428,7 @@ RootObject compileTypeMixin(TypeMixin tm, ref const Loc loc, Scope* sc)
auto locm = adjustLocForMixin(str, loc, global.params.mixinOut);
scope p = new Parser!ASTCodegen(locm, sc._module, str, false, global.errorSink, &global.compileEnv, doUnittests);
p.transitionIn = global.params.v.vin;
p.allowPrivateThis = global.params.privateThis;
p.nextToken();
//printf("p.loc.linnum = %d\n", p.loc.linnum);

Expand Down
1 change: 1 addition & 0 deletions compiler/test/compilable/previewhelp.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Upcoming language changes listed by -preview=name:
=in `in` on parameters means `scope const [ref]` and accepts rvalues
=inclusiveincontracts 'in' contracts of overridden methods must be a superset of parent contract
=fixImmutableConv disallow unsound immutable conversions that were formerly incorrectly permitted
=privateThis add `private(this)` visibility attribute, private to the class/struct/union instead of module
=systemVariables disable access to variables marked '@system' from @safe code
----
*/
63 changes: 63 additions & 0 deletions test/fail_compilation/prot_privatethis.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
REQUIRED_ARGS: -preview=privateThis
TEST_OUTPUT:
---
fail_compilation/prot_privatethis.d(35): Error: no property `secret` for type `prot_privatethis.C.Nested`
fail_compilation/prot_privatethis.d(56): Error: no property `secret` for type `prot_privatethis.C`
fail_compilation/prot_privatethis.d(57): Error: no property `internalFunc` for type `prot_privatethis.C`
fail_compilation/prot_privatethis.d(58): Error: no property `mixedInSecret` for type `prot_privatethis.C`
fail_compilation/prot_privatethis.d(61): Error: no property `secret` for type `prot_privatethis.U`
---
*/

mixin template MT()
{
private(this) string mixedInSecret;
void accessSecret() { secret++; }
}

class C
{
private(this) int secret;
mixin MT!();

struct Nested
{
private(this) int secret;
void setSecret(int secret) { this.secret = secret; }
}

Nested nested;

this(int secret)
{
this.secret = secret;
nested.secret = 3; // no access
nested.setSecret(3); // access
mixedInSecret = "s"; // access
internalFunc(); // access
accessSecret(); // access
}

private(this) void internalFunc() { }
}

static assert(__traits(getVisibility, C.secret) == "private(this)");

union U
{
private(this) int secret;
private int butNotReally;
}

void main()
{
C c = new C(2);
assert(c.secret == 2); // no access
c.internalFunc(); // no access
c.mixedInSecret = ""; // no access

U u;
u.secret = 3; // no access
u.butNotReally = 4; // access
}
18 changes: 18 additions & 0 deletions test/fail_compilation/prot_privatethis_global.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
REQUIRED_ARGS: -preview=privateThis
TEST_OUTPUT:
---
fail_compilation/prot_privatethis_global.d(11): Error: `private(this)` cannot be used in global scope
fail_compilation/prot_privatethis_global.d(13): Error: `private(this)` cannot be used in global scope
fail_compilation/prot_privatethis_global.d(16): Error: `private(this)` cannot be used in global scope
---
*/

private(this) int x;

private(this): int y;

private(this)
{
int z;
}
11 changes: 11 additions & 0 deletions test/fail_compilation/prot_privatethis_preview.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
TEST_OUTPUT:
---
fail_compilation/prot_privatethis_preview.d(10): Error: use `-preview=privateThis` to enable usage of `private(this)`
---
*/

class C
{
private(this) int x;
}