Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/dmd/cli.d
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,8 @@ dmd -cov -unittest myprog.d
"`in` on parameters means `scope const [ref]` and accepts rvalues"),
Feature("inclusiveincontracts", "inclusiveInContracts",
"'in' contracts of overridden methods must be a superset of parent contract"),
Feature("shortenedMethods", "shortenedMethods",
"allow use of => for methods and top-level functions in addition to lambdas"),
// DEPRECATED previews
// trigger deprecation message once D repositories don't use this flag anymore
Feature("markdown", "markdown", "enable Markdown replacements in Ddoc", false, false),
Expand Down
2 changes: 2 additions & 0 deletions src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -7033,6 +7033,7 @@ struct Param
bool useExceptions;
bool noSharedAccess;
bool previewIn;
bool shortenedMethods;
bool betterC;
bool addMain;
bool allInst;
Expand Down Expand Up @@ -7173,6 +7174,7 @@ struct Param
useExceptions(true),
noSharedAccess(),
previewIn(),
shortenedMethods(),
betterC(),
addMain(),
allInst(),
Expand Down
1 change: 1 addition & 0 deletions src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ extern (C++) struct Param
bool useExceptions = true; // support exception handling
bool noSharedAccess; // read/write access to shared memory objects
bool previewIn; // `in` means `[ref] scope const`, accepts rvalues
bool shortenedMethods; // allow => in normal function declarations
bool betterC; // be a "better C" compiler; no dependency on D runtime
bool addMain; // add a default main() function
bool allInst; // generate code for all template instantiations
Expand Down
1 change: 1 addition & 0 deletions src/dmd/globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct Param
bool useExceptions; // support exception handling
bool noSharedAccess; // read/write access to shared memory objects
bool previewIn; // `in` means `scope const`, perhaps `ref`, accepts rvalues
bool shortenedMethods; // allow => in normal function declarations
bool betterC; // be a "better C" compiler; no dependency on D runtime
bool addMain; // add a default main() function
bool allInst; // generate code for all template instantiations
Expand Down
16 changes: 14 additions & 2 deletions src/dmd/parse.d
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ final class Parser(AST) : Lexer
Token* tk;
if (token.value == TOK.identifier && skipParens(peek(&token), &tk) && skipAttributes(tk, &tk) &&
(tk.value == TOK.leftParentheses || tk.value == TOK.leftCurly || tk.value == TOK.in_ ||
tk.value == TOK.out_ || tk.value == TOK.do_ ||
tk.value == TOK.out_ || tk.value == TOK.do_ || tk.value == TOK.goesTo ||
tk.value == TOK.identifier && tk.ident == Id._body))
{
version (none)
Expand Down Expand Up @@ -4753,7 +4753,7 @@ final class Parser(AST) : Lexer
Token* tk;
if ((storage_class || udas) && token.value == TOK.identifier && skipParens(peek(&token), &tk) &&
skipAttributes(tk, &tk) &&
(tk.value == TOK.leftParentheses || tk.value == TOK.leftCurly || tk.value == TOK.in_ || tk.value == TOK.out_ ||
(tk.value == TOK.leftParentheses || tk.value == TOK.leftCurly || tk.value == TOK.in_ || tk.value == TOK.out_ || tk.value == TOK.goesTo ||
tk.value == TOK.do_ || tk.value == TOK.identifier && tk.ident == Id._body))
{
version (none)
Expand Down Expand Up @@ -5119,6 +5119,18 @@ final class Parser(AST) : Lexer
L1:
switch (token.value)
{
case TOK.goesTo:
if (requireDo)
error("missing `do { ... }` after `in` or `out`");
if (!global.params.shortenedMethods)
error("=> shortened method not enabled, compile with compiler switch `-preview=shortenedMethods`");
const returnloc = token.loc;
nextToken();
f.fbody = new AST.ReturnStatement(returnloc, parseExpression());
f.endloc = token.loc;
check(TOK.semicolon);
break;

case TOK.leftCurly:
if (requireDo)
error("missing `do { ... }` after `in` or `out`");
Expand Down
1 change: 1 addition & 0 deletions test/compilable/previewhelp.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ Upcoming language changes listed by -preview=name:
=nosharedaccess disable access to shared memory objects
=in `in` on parameters means `scope const [ref]` and accepts rvalues
=inclusiveincontracts 'in' contracts of overridden methods must be a superset of parent contract
=shortenedMethods allow use of => for methods and top-level functions in addition to lambdas
----
*/
33 changes: 33 additions & 0 deletions test/compilable/shortened_methods.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// REQUIRED_ARGS: -preview=shortenedMethods
class A {
int _x = 34;
// short syntax works in all contexts
@property x() => _x;
@property x(int v) => _x = v;

// including with contracts
@property y() in(true) => _x;

// or other auto returns
auto foo() @safe => assert(0);

// or normal method defintions
bool isNull() => this is null;
}

class B : A{
// short syntax also overrides the same as long syntax
override bool isNull() => this !is null;
}

static assert((new A).x == 34);

string test() => "hello"; // works at any scope

static assert(test() == "hello"); // works normally
static assert(is(typeof(&test) == string function())); // same normal type

void func() {
int a;
int nested() => a; // and at nested scopes too
}