From a80d302a2f226f4ba0c45ed7b0a214aa2095f51f Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Sat, 7 Dec 2024 13:19:33 +0000 Subject: [PATCH] Don't allow short constructor with non-void expression Follow up to #17079. --- compiler/src/dmd/dsymbolsem.d | 18 ++++++++++++++++++ compiler/test/compilable/shortened_methods.d | 2 +- compiler/test/fail_compilation/short_fn.d | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 compiler/test/fail_compilation/short_fn.d diff --git a/compiler/src/dmd/dsymbolsem.d b/compiler/src/dmd/dsymbolsem.d index 173532af397c..65aab8a6dedc 100644 --- a/compiler/src/dmd/dsymbolsem.d +++ b/compiler/src/dmd/dsymbolsem.d @@ -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(); diff --git a/compiler/test/compilable/shortened_methods.d b/compiler/test/compilable/shortened_methods.d index 81d6da8734e1..76a4c8a55db6 100644 --- a/compiler/test/compilable/shortened_methods.d +++ b/compiler/test/compilable/shortened_methods.d @@ -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); } diff --git a/compiler/test/fail_compilation/short_fn.d b/compiler/test/fail_compilation/short_fn.d new file mode 100644 index 000000000000..04f3e3fffbfa --- /dev/null +++ b/compiler/test/fail_compilation/short_fn.d @@ -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(); +}