mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Don't allow short constructor with non-void expression except this()
and super()
(#17489)
This commit is contained in:
parent
a13b00fab1
commit
a7f6b04a0c
4 changed files with 38 additions and 2 deletions
|
@ -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`.
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
15
compiler/test/fail_compilation/short_fn.d
Normal file
15
compiler/test/fail_compilation/short_fn.d
Normal 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();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue