diff --git a/changelog/dmd.shortened-method-constructor.dd b/changelog/dmd.shortened-method-constructor.dd new file mode 100644 index 0000000000..c66e61b261 --- /dev/null +++ b/changelog/dmd.shortened-method-constructor.dd @@ -0,0 +1,15 @@ +Shortened method syntax can now be used in constructors + +This used to raise an error "cannot return expression from constructor", but it's now supported: + +--- +struct Number +{ + int x; + + this(int x) => this.x = x; + this(float x) => this(cast(int) x); +} +--- + +Postblits and destructors already supported shortened method syntax because they return `void`. diff --git a/compiler/src/dmd/parse.d b/compiler/src/dmd/parse.d index 3e145be549..43fcaf9335 100644 --- a/compiler/src/dmd/parse.d +++ b/compiler/src/dmd/parse.d @@ -5252,7 +5252,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer error("missing `do { ... }` after `in` or `out`"); const returnloc = token.loc; nextToken(); - f.fbody = new AST.ReturnStatement(returnloc, parseExpression()); + if (f.isCtorDeclaration) + f.fbody = new AST.ExpStatement(returnloc, parseExpression()); + else + f.fbody = new AST.ReturnStatement(returnloc, parseExpression()); f.endloc = token.loc; check(TOK.semicolon); break; diff --git a/compiler/test/compilable/shortened_methods.d b/compiler/test/compilable/shortened_methods.d index 785cb8e5cd..81d6da8734 100644 --- a/compiler/test/compilable/shortened_methods.d +++ b/compiler/test/compilable/shortened_methods.d @@ -13,6 +13,10 @@ class A { // or normal method defintions bool isNull() => this is null; + + this() {} + this(int x) => _x = x; + this(float y) => this(cast(int) y); } class B : A{ @@ -36,3 +40,12 @@ void func() { // Issue 24088 - https://issues.dlang.org/show_bug.cgi?id=24088 S!int f() => S!int(); } + +struct T +{ + void inc() {} + this(this) => inc(); + + void free() {} + ~this() => free(); +}