Skip to content

Commit

Permalink
Don't allow short constructor with non-void expression except `this()…
Browse files Browse the repository at this point in the history
…` and `super()` (#17489)
  • Loading branch information
ntrel authored Dec 8, 2024
1 parent a13b00f commit a7f6b04
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
5 changes: 4 additions & 1 deletion changelog/dmd.shortened-method-constructor.dd
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ struct Number
{
int x;

this(int x) => this.x = x;
void vf(int);
this(int x) => vf(x);
this(float x) => this(cast(int) x);
}
---

The expression body must be a `this`/`super` call or have type `void`.

Postblits and destructors already supported shortened method syntax because they return `void`.
18 changes: 18 additions & 0 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,24 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
sc.stc &= ~STC.static_; // not a static constructor

funcDeclarationSemantic(sc, ctd);
// Check short constructor: this() => expr;
if (ctd.fbody)
{
if (auto s = ctd.fbody.isExpStatement())
{
if (s.exp)
{
auto ce = s.exp.isCallExp();
// check this/super before semantic
if (!ce || (!ce.e1.isThisExp() && !ce.e1.isSuperExp()))
{
s.exp = s.exp.expressionSemantic(sc);
if (s.exp.type.ty != Tvoid)
error(s.loc, "can only return void expression, `this` call or `super` call from constructor");
}
}
}
}

sc.pop();

Expand Down
2 changes: 1 addition & 1 deletion compiler/test/compilable/shortened_methods.d
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class A {
bool isNull() => this is null;

this() {}
this(int x) => _x = x;
this(int x) { _x = x; }
this(float y) => this(cast(int) y);
}

Expand Down
15 changes: 15 additions & 0 deletions compiler/test/fail_compilation/short_fn.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
TEST_OUTPUT:
---
fail_compilation/short_fn.d(13): Error: can only return void expression, `this` call or `super` call from constructor
fail_compilation/short_fn.d(14): Error: can only return void expression, `this` call or `super` call from constructor
---
*/

struct Number
{
int x;

this(int x) => this.x = x;
this(byte x) => Number();
}

0 comments on commit a7f6b04

Please sign in to comment.