Don't allow short constructor with non-void expression except this() and super() (#17489)

This commit is contained in:
Nick Treleaven 2024-12-08 09:21:42 +00:00 committed by GitHub
parent a13b00fab1
commit a7f6b04a0c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 38 additions and 2 deletions

View file

@ -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`.

View file

@ -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();

View file

@ -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);
}

View file

@ -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();
}