From bf389864ca7cde3b289625522ab0b897177d1c33 Mon Sep 17 00:00:00 2001 From: Dennis Korpel Date: Thu, 21 Nov 2024 21:20:09 +0100 Subject: [PATCH] Allow shortened method syntax for constructors --- changelog/dmd.shortened-method-constructor.dd | 15 +++++++++++++++ compiler/src/dmd/parse.d | 5 ++++- compiler/test/compilable/shortened_methods.d | 13 +++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 changelog/dmd.shortened-method-constructor.dd diff --git a/changelog/dmd.shortened-method-constructor.dd b/changelog/dmd.shortened-method-constructor.dd new file mode 100644 index 000000000000..c66e61b261cc --- /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 3e145be5499f..43fcaf933545 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 785cb8e5cd0a..81d6da8734e1 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(); +}