Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable -preview=rvaluerefparam #17068

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions changelog/dmd.enable-rvaluerefparam.dd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Enabled -preview=rvaluerefparam after a long testing period.

You can now supply an rvalue to a ref argument. A temporary will automatically be created for the call.
6 changes: 3 additions & 3 deletions compiler/src/dmd/cli.d
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,9 @@ dmd -cov -unittest myprog.d
Feature("dtorfields", "dtorFields", "don't destruct fields of partially constructed objects"),
Feature("fieldwise", "fieldwise", "don't use fieldwise comparisons for struct equality",
"https://dlang.org/changelog/2.085.0.html#no-cmpsb"),
Feature("rvaluerefparam", "rvalueRefParam",
"revert rvalue arguments to ref parameters",
"https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a"),
];

/// Returns all available previews
Expand Down Expand Up @@ -976,9 +979,6 @@ dmd -cov -unittest myprog.d
Feature("dtorfields", "dtorFields",
"destruct fields of partially constructed objects",
"https://dlang.org/changelog/2.098.0.html#dtorfileds", false, false),
Feature("rvaluerefparam", "rvalueRefParam",
"enable rvalue arguments to ref parameters",
"https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a"),
Feature("safer", "safer",
"more safety checks by default",
"https://github.com/WalterBright/documents/blob/38f0a846726b571f8108f6e63e5e217b91421c86/safer.md", true, false),
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/dscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private struct Previews
this.in_ = params.previewIn;
this.inclusiveInContracts = params.inclusiveInContracts;
this.noSharedAccess = params.noSharedAccess == FeatureState.enabled;
this.rvalueRefParam = params.rvalueRefParam == FeatureState.enabled;
this.rvalueRefParam = params.rvalueRefParam != FeatureState.disabled;
this.safer = params.safer == FeatureState.enabled;
this.systemVariables = params.systemVariables;
}
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dmd/frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -8450,6 +8450,7 @@ struct Param final
ehnogc(),
useDIP1021(),
fixAliasThis(),
rvalueRefParam((FeatureState)2u),
previewIn(),
inclusiveInContracts(),
shortenedMethods(true),
Expand Down Expand Up @@ -8500,7 +8501,7 @@ struct Param final
timeTraceFile()
{
}
Param(bool obj, bool multiobj = false, bool trace = false, bool tracegc = false, bool vcg_ast = false, DiagnosticReporting useDeprecated = (DiagnosticReporting)1u, bool useUnitTests = false, bool useInline = false, bool release = false, bool preservePaths = false, DiagnosticReporting useWarnings = (DiagnosticReporting)2u, bool cov = false, uint8_t covPercent = 0u, bool ctfe_cov = false, bool ignoreUnsupportedPragmas = true, bool useModuleInfo = true, bool useTypeInfo = true, bool useExceptions = true, bool useGC = true, bool betterC = false, bool addMain = false, bool allInst = false, bool bitfields = false, CppStdRevision cplusplus = (CppStdRevision)201103u, Help help = Help(), Verbose v = Verbose(), FeatureState useDIP25 = (FeatureState)2u, FeatureState useDIP1000 = (FeatureState)0u, bool ehnogc = false, bool useDIP1021 = false, FeatureState fieldwise = (FeatureState)0u, bool fixAliasThis = false, FeatureState rvalueRefParam = (FeatureState)0u, FeatureState safer = (FeatureState)0u, FeatureState noSharedAccess = (FeatureState)0u, bool previewIn = false, bool inclusiveInContracts = false, bool shortenedMethods = true, bool fixImmutableConv = false, bool fix16997 = true, FeatureState dtorFields = (FeatureState)0u, FeatureState systemVariables = (FeatureState)0u, CHECKENABLE useInvariants = (CHECKENABLE)0u, CHECKENABLE useIn = (CHECKENABLE)0u, CHECKENABLE useOut = (CHECKENABLE)0u, CHECKENABLE useArrayBounds = (CHECKENABLE)0u, CHECKENABLE useAssert = (CHECKENABLE)0u, CHECKENABLE useSwitchError = (CHECKENABLE)0u, CHECKENABLE boundscheck = (CHECKENABLE)0u, CHECKACTION checkAction = (CHECKACTION)0u, CLIIdentifierTable dIdentifierTable = (CLIIdentifierTable)0u, CLIIdentifierTable cIdentifierTable = (CLIIdentifierTable)0u, _d_dynamicArray< const char > argv0 = {}, Array<const char* > modFileAliasStrings = Array<const char* >(), Array<const char* > imppath = Array<const char* >(), Array<const char* > fileImppath = Array<const char* >(), _d_dynamicArray< const char > objdir = {}, _d_dynamicArray< const char > objname = {}, _d_dynamicArray< const char > libname = {}, Output ddoc = Output(), Output dihdr = Output(), Output cxxhdr = Output(), Output json = Output(), JsonFieldFlags jsonFieldFlags = (JsonFieldFlags)0u, Output makeDeps = Output(), Output mixinOut = Output(), Output moduleDeps = Output(), uint32_t debuglevel = 0u, uint32_t versionlevel = 0u, bool run = false, Array<const char* > runargs = Array<const char* >(), Array<const char* > cppswitches = Array<const char* >(), const char* cpp = nullptr, Array<const char* > objfiles = Array<const char* >(), Array<const char* > linkswitches = Array<const char* >(), Array<bool > linkswitchIsForCC = Array<bool >(), Array<const char* > libfiles = Array<const char* >(), Array<const char* > dllfiles = Array<const char* >(), _d_dynamicArray< const char > deffile = {}, _d_dynamicArray< const char > resfile = {}, _d_dynamicArray< const char > exefile = {}, _d_dynamicArray< const char > mapfile = {}, bool fullyQualifiedObjectFiles = false, bool timeTrace = false, uint32_t timeTraceGranularityUs = 500u, const char* timeTraceFile = nullptr) :
Param(bool obj, bool multiobj = false, bool trace = false, bool tracegc = false, bool vcg_ast = false, DiagnosticReporting useDeprecated = (DiagnosticReporting)1u, bool useUnitTests = false, bool useInline = false, bool release = false, bool preservePaths = false, DiagnosticReporting useWarnings = (DiagnosticReporting)2u, bool cov = false, uint8_t covPercent = 0u, bool ctfe_cov = false, bool ignoreUnsupportedPragmas = true, bool useModuleInfo = true, bool useTypeInfo = true, bool useExceptions = true, bool useGC = true, bool betterC = false, bool addMain = false, bool allInst = false, bool bitfields = false, CppStdRevision cplusplus = (CppStdRevision)201103u, Help help = Help(), Verbose v = Verbose(), FeatureState useDIP25 = (FeatureState)2u, FeatureState useDIP1000 = (FeatureState)0u, bool ehnogc = false, bool useDIP1021 = false, FeatureState fieldwise = (FeatureState)0u, bool fixAliasThis = false, FeatureState rvalueRefParam = (FeatureState)2u, FeatureState safer = (FeatureState)0u, FeatureState noSharedAccess = (FeatureState)0u, bool previewIn = false, bool inclusiveInContracts = false, bool shortenedMethods = true, bool fixImmutableConv = false, bool fix16997 = true, FeatureState dtorFields = (FeatureState)0u, FeatureState systemVariables = (FeatureState)0u, CHECKENABLE useInvariants = (CHECKENABLE)0u, CHECKENABLE useIn = (CHECKENABLE)0u, CHECKENABLE useOut = (CHECKENABLE)0u, CHECKENABLE useArrayBounds = (CHECKENABLE)0u, CHECKENABLE useAssert = (CHECKENABLE)0u, CHECKENABLE useSwitchError = (CHECKENABLE)0u, CHECKENABLE boundscheck = (CHECKENABLE)0u, CHECKACTION checkAction = (CHECKACTION)0u, CLIIdentifierTable dIdentifierTable = (CLIIdentifierTable)0u, CLIIdentifierTable cIdentifierTable = (CLIIdentifierTable)0u, _d_dynamicArray< const char > argv0 = {}, Array<const char* > modFileAliasStrings = Array<const char* >(), Array<const char* > imppath = Array<const char* >(), Array<const char* > fileImppath = Array<const char* >(), _d_dynamicArray< const char > objdir = {}, _d_dynamicArray< const char > objname = {}, _d_dynamicArray< const char > libname = {}, Output ddoc = Output(), Output dihdr = Output(), Output cxxhdr = Output(), Output json = Output(), JsonFieldFlags jsonFieldFlags = (JsonFieldFlags)0u, Output makeDeps = Output(), Output mixinOut = Output(), Output moduleDeps = Output(), uint32_t debuglevel = 0u, uint32_t versionlevel = 0u, bool run = false, Array<const char* > runargs = Array<const char* >(), Array<const char* > cppswitches = Array<const char* >(), const char* cpp = nullptr, Array<const char* > objfiles = Array<const char* >(), Array<const char* > linkswitches = Array<const char* >(), Array<bool > linkswitchIsForCC = Array<bool >(), Array<const char* > libfiles = Array<const char* >(), Array<const char* > dllfiles = Array<const char* >(), _d_dynamicArray< const char > deffile = {}, _d_dynamicArray< const char > resfile = {}, _d_dynamicArray< const char > exefile = {}, _d_dynamicArray< const char > mapfile = {}, bool fullyQualifiedObjectFiles = false, bool timeTrace = false, uint32_t timeTraceGranularityUs = 500u, const char* timeTraceFile = nullptr) :
obj(obj),
multiobj(multiobj),
trace(trace),
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/globals.d
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ extern (C++) struct Param
bool useDIP1021; // implement https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md
FeatureState fieldwise; // do struct equality testing field-wise rather than by memcmp()
bool fixAliasThis; // if the current scope has an alias this, check it before searching upper scopes
FeatureState rvalueRefParam; // allow rvalues to be arguments to ref parameters
FeatureState rvalueRefParam = FeatureState.enabled; // allow rvalues to be arguments to ref parameters
// https://dconf.org/2019/talks/alexandrescu.html
// https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a
// https://digitalmars.com/d/archives/digitalmars/D/Binding_rvalues_to_ref_parameters_redux_325087.html
Expand Down
5 changes: 3 additions & 2 deletions compiler/src/dmd/typesem.d
Original file line number Diff line number Diff line change
Expand Up @@ -2335,8 +2335,9 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)

// default arg must be an lvalue
if (isRefOrOut && !isAuto &&
!(fparam.storageClass & STC.constscoperef) && !sc.previews.rvalueRefParam)
e = e.toLvalue(sc, "create default argument for `ref` / `out` parameter from");
!(fparam.storageClass & STC.constscoperef) &&
(!sc.previews.rvalueRefParam || (fparam.storageClass & STC.out_)))
e = e.toLvalue(sc, (global.params.rvalueRefParam != FeatureState.disabled) ? "create default argument for `out` parameter from" : "create default argument for `ref` / `out` parameter from");

fparam.defaultArg = e;
return (e.op != EXP.error);
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/compilable/fix21647.d
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
REQUIRED_ARGS: -preview=rvaluerefparam
REQUIRED_ARGS:
TEST_OUTPUT:
---
cast(void)0
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/compilable/issue20704.d
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
https://issues.dlang.org/show_bug.cgi?id=20704
REQUIRED_ARGS: -preview=rvaluerefparam
REQUIRED_ARGS:
*/

void f1(T)(const auto ref T arg = T.init) {}
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/compilable/issue20705.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// REQUIRED_ARGS: -preview=rvaluerefparam
// REQUIRED_ARGS:
struct Foo
{
int[] a;
Expand Down
1 change: 0 additions & 1 deletion compiler/test/compilable/previewhelp.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Upcoming language changes listed by -preview=name:
=dip1021 implement Mutable Function Arguments DIP (https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1021.md)
=bitfields add C-like bitfields (https://github.com/dlang/dlang.org/pull/3190)
=fixAliasThis when a symbol is resolved, check alias this scope before going to upper scopes (https://github.com/dlang/dmd/pull/8885)
=rvaluerefparam enable rvalue arguments to ref parameters (https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a)
=safer more safety checks by default (https://github.com/WalterBright/documents/blob/38f0a846726b571f8108f6e63e5e217b91421c86/safer.md)
=nosharedaccess disable access to shared memory objects (https://dlang.org/spec/const3.html#shared)
=in `in` on parameters means `scope const [ref]` and accepts rvalues (https://dlang.org/spec/function.html#in-params)
Expand Down
1 change: 1 addition & 0 deletions compiler/test/compilable/reverthelp.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ Revertable language changes listed by -revert=name:
=intpromote revert integral promotions for unary + - ~ operators
=dtorfields don't destruct fields of partially constructed objects
=fieldwise don't use fieldwise comparisons for struct equality (https://dlang.org/changelog/2.085.0.html#no-cmpsb)
=rvaluerefparam revert rvalue arguments to ref parameters (https://gist.github.com/andralex/e5405a5d773f07f73196c05f8339435a)
----
*/
2 changes: 1 addition & 1 deletion compiler/test/compilable/rvalue2.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* PERMUTE_ARGS: -preview=rvaluerefparam
/* PERMUTE_ARGS: -revert=rvaluerefparam
*/

struct S
Expand Down
2 changes: 1 addition & 1 deletion compiler/test/compilable/rvalueref.d
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* REQUIRED_ARGS: -preview=rvaluerefparam
/* REQUIRED_ARGS:
*/

struct AS
Expand Down
4 changes: 4 additions & 0 deletions compiler/test/compilable/test18216.d
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// TODO: hack, make this test work with rvaluerefparam. With ref parameters, opAssign generation triggers:
// compilable/test18216.d(17): Error: struct `test18216.Node` no size because of forward reference
//
// REQUIRED_ARGS: -revert=rvaluerefparam
// https://issues.dlang.org/show_bug.cgi?id=18216

struct Node
Expand Down
20 changes: 7 additions & 13 deletions compiler/test/fail_compilation/b20011.d
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
/*
TEST_OUTPUT:
---
fail_compilation/b20011.d(28): Error: cannot modify expression `S1(cast(ubyte)0u).member` because it is not an lvalue
fail_compilation/b20011.d(31): Error: cannot modify expression `S2(null).member` because it is not an lvalue
fail_compilation/b20011.d(32): Error: cannot modify expression `S2(null).member` because it is not an lvalue
fail_compilation/b20011.d(35): Error: cannot modify expression `U1(cast(ubyte)0u, ).m2` because it is not an lvalue
fail_compilation/b20011.d(40): Error: function `assignableByRef` is not callable using argument types `(ubyte)`
fail_compilation/b20011.d(40): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref ubyte p`
fail_compilation/b20011.d(37): `b20011.main.assignableByRef(ref ubyte p)` declared here
fail_compilation/b20011.d(41): Error: function `assignableByOut` is not callable using argument types `(ubyte)`
fail_compilation/b20011.d(41): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `out ubyte p`
fail_compilation/b20011.d(38): `b20011.main.assignableByOut(out ubyte p)` declared here
fail_compilation/b20011.d(42): Error: function `assignableByConstRef` is not callable using argument types `(ubyte)`
fail_compilation/b20011.d(42): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `ref const(ubyte) p`
fail_compilation/b20011.d(39): `b20011.main.assignableByConstRef(ref const(ubyte) p)` declared here
fail_compilation/b20011.d(22): Error: cannot modify expression `S1(cast(ubyte)0u).member` because it is not an lvalue
fail_compilation/b20011.d(25): Error: cannot modify expression `S2(null).member` because it is not an lvalue
fail_compilation/b20011.d(26): Error: cannot modify expression `S2(null).member` because it is not an lvalue
fail_compilation/b20011.d(29): Error: cannot modify expression `U1(cast(ubyte)0u, ).m2` because it is not an lvalue
fail_compilation/b20011.d(35): Error: function `assignableByOut` is not callable using argument types `(ubyte)`
fail_compilation/b20011.d(35): cannot pass rvalue argument `S1(cast(ubyte)0u).member` of type `ubyte` to parameter `out ubyte p`
fail_compilation/b20011.d(32): `b20011.main.assignableByOut(out ubyte p)` declared here
---
*/
module b20011;
Expand Down
4 changes: 1 addition & 3 deletions compiler/test/fail_compilation/fail20183.d
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/* REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
fail_compilation/fail20183.d(1016): Error: function `addr` is not callable using argument types `(int)`
fail_compilation/fail20183.d(1016): cannot pass rvalue argument `S(0).i` of type `int` to parameter `return ref int b`
fail_compilation/fail20183.d(1004): `fail20183.addr(return ref int b)` declared here
fail_compilation/fail20183.d(1016): Error: address of variable `__rvalue2` assigned to `p` with longer lifetime
fail_compilation/fail20183.d(1017): Error: address of expression temporary returned by `s()` assigned to `q` with longer lifetime
fail_compilation/fail20183.d(1018): Error: address of struct literal `S(0)` assigned to `r` with longer lifetime
---
Expand Down
7 changes: 0 additions & 7 deletions compiler/test/fail_compilation/fail7603a.d

This file was deleted.

2 changes: 1 addition & 1 deletion compiler/test/fail_compilation/fail7603b.d
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail7603b.d(7): Error: cannot create default argument for `ref` / `out` parameter from constant `true`
fail_compilation/fail7603b.d(7): Error: cannot create default argument for `out` parameter from constant `true`
---
*/
void test(out bool val = true) { }
8 changes: 0 additions & 8 deletions compiler/test/fail_compilation/fail7603c.d

This file was deleted.

10 changes: 0 additions & 10 deletions compiler/test/fail_compilation/fail9773.d

This file was deleted.

10 changes: 2 additions & 8 deletions compiler/test/fail_compilation/fail9891.d
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail9891.d(13): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `ref int` of parameter `n`
fail_compilation/fail9891.d(18): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `out int` of parameter `n`
fail_compilation/fail9891.d(23): Error: cannot create default argument for `ref` / `out` parameter from expression `prop()` because it is not an lvalue
fail_compilation/fail9891.d(12): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `ref int` of parameter `n`
fail_compilation/fail9891.d(17): Error: expression `i` of type `immutable(int)` is not implicitly convertible to type `out int` of parameter `n`
---
*/

Expand All @@ -19,8 +18,3 @@ void f2(out int n = i)
{
++n;
}

void f3(ref int n = prop)
{
++n;
}
39 changes: 0 additions & 39 deletions compiler/test/fail_compilation/issue20704.d

This file was deleted.

30 changes: 0 additions & 30 deletions compiler/test/fail_compilation/test21807.d
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,3 @@ class Foo
ca = getSArray();
}
}

/*
TEST_OUTPUT:
---
fail_compilation/test21807.d(117): Error: function `addr` is not callable using argument types `(int)`
fail_compilation/test21807.d(117): cannot pass rvalue argument `S(0).i` of type `int` to parameter `return ref int b`
fail_compilation/test21807.d(106): `test21807.addr(return ref int b)` declared here
---
*/
#line 100

struct S
{
int i;
}

int* addr(return ref int b)
{
return &b;
}

class Foo2
{
int* ptr;

this()
{
ptr = addr(S().i); // struct temporary
}
}
Loading
Loading