Skip to content

Commit 08dddfb

Browse files
committed
Disallow initializing fields with themself
1 parent 4ad3fc7 commit 08dddfb

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

compiler/src/dmd/expressionsem.d

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10616,6 +10616,33 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
1061610616
if (exp.op == EXP.assign
1061710617
&& exp.e1.checkModifiable(sc) == Modifiable.initialization)
1061810618
{
10619+
// Check common mistake of misspelled parameters in constructors,
10620+
// e.g. `this(int feild) { this.field = field; }`
10621+
if (auto dve1 = exp.e1.isDotVarExp)
10622+
if (auto dve2 = exp.e2.isDotVarExp)
10623+
if (sc.func && sc.func.parameters && dve1.e1.isThisExp && dve2.e1.isThisExp()
10624+
&& dve1.var.ident.equals(dve2.var.ident))
10625+
{
10626+
error(exp.e1.loc, "Cannot initialize field `%s` with itself", dve1.var.toChars());
10627+
auto findParameter(const(char)[] s, ref int cost)
10628+
{
10629+
foreach (p; *sc.func.parameters)
10630+
{
10631+
if (p.ident.toString == s)
10632+
{
10633+
cost = 1;
10634+
return p.ident.toString;
10635+
}
10636+
}
10637+
return null;
10638+
}
10639+
import dmd.root.speller : speller;
10640+
if (auto s = speller!findParameter(dve1.var.ident.toString))
10641+
{
10642+
errorSupplemental(sc.func.loc, "Did you mean to use parameter `%.*s`?\n", s.fTuple.expand);
10643+
}
10644+
}
10645+
1061910646
//printf("[%s] change to init - %s\n", exp.loc.toChars(), exp.toChars());
1062010647
auto t = exp.type;
1062110648
exp = new ConstructExp(exp.loc, exp.e1, exp.e2);

compiler/test/compilable/interpret3.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6240,9 +6240,9 @@ struct Coord13831
62406240

62416241
struct Chunk13831
62426242
{
6243-
this(Coord13831)
6243+
this(Coord13831 coord)
62446244
{
6245-
coord = coord;
6245+
this.coord = coord;
62466246
}
62476247

62486248
Coord13831 coord;

compiler/test/compilable/test22510.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct S
77
@disable this(this);
88
this (scope ref inout S) inout
99
{
10-
this.b = b;
10+
this.b = 0;
1111
}
1212
}
1313

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
TEST_OUTPUT:
3+
---
4+
fail_compilation/ctor_self_assignment.d(16): Error: Cannot initialize field `location` with itself
5+
fail_compilation/ctor_self_assignment.d(14): Did you mean to use parameter `locaction`?
6+
---
7+
*/
8+
// https://forum.dlang.org/post/teghfhpmvkdcfwfeovua@forum.dlang.org
9+
10+
alias Location = int;
11+
12+
struct Node
13+
{
14+
this(Location locaction, uint f)
15+
{
16+
this.location = location;
17+
this.f = f;
18+
}
19+
20+
Location location;
21+
uint f;
22+
}

0 commit comments

Comments
 (0)