From 0c77177c1702a7029e92d237d203dce5ce2f3160 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Wed, 23 Oct 2019 12:30:43 +0200 Subject: [PATCH 1/5] Make `in` mean `scope const` in DIP1000 --- src/dmd/parse.d | 10 +++++++++- test/compilable/test_in_scope_const.d | 13 +++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 test/compilable/test_in_scope_const.d diff --git a/src/dmd/parse.d b/src/dmd/parse.d index 16e430f94f7a..fd4e6319eccd 100644 --- a/src/dmd/parse.d +++ b/src/dmd/parse.d @@ -2864,7 +2864,15 @@ final class Parser(AST) : Lexer // Don't call nextToken again. } case TOK.in_: - stc = STC.in_; + // Make `in` mean `const scope` if DIP1000 is selected + if (global.params.vsafe) + { + stc = STC.const_ | STC.scope_; + } + else + { + stc = STC.in_; + } goto L2; case TOK.out_: diff --git a/test/compilable/test_in_scope_const.d b/test/compilable/test_in_scope_const.d new file mode 100644 index 000000000000..ec17c202481d --- /dev/null +++ b/test/compilable/test_in_scope_const.d @@ -0,0 +1,13 @@ +/* REQUIRED_ARGS: -preview=dip1000 + */ + +@safe: + +import std.traits: ParameterStorageClassTuple, ParameterStorageClass, Parameters; + +void fun(in int* inParam); +alias storages = ParameterStorageClassTuple!fun; +alias storage = storages[0]; + +static assert(is(Parameters!fun[0] == const int*)); +static assert(storage & ParameterStorageClass.scope_); From ff3542c18ac7ea33d47b504773cbae5ff0c1845e Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Wed, 30 Oct 2019 12:05:11 +0100 Subject: [PATCH 2/5] Fix linker errors by having `in` always mean `const scope` --- src/dmd/parse.d | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/dmd/parse.d b/src/dmd/parse.d index fd4e6319eccd..c0192f6de741 100644 --- a/src/dmd/parse.d +++ b/src/dmd/parse.d @@ -2864,15 +2864,8 @@ final class Parser(AST) : Lexer // Don't call nextToken again. } case TOK.in_: - // Make `in` mean `const scope` if DIP1000 is selected - if (global.params.vsafe) - { - stc = STC.const_ | STC.scope_; - } - else - { - stc = STC.in_; - } + // `in` now means `const scope` as originally intented + stc = STC.const_ | STC.scope_; goto L2; case TOK.out_: From 01f0297c61cb729558ac668ec1ae5aae5fe81728 Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Wed, 30 Oct 2019 15:35:31 +0100 Subject: [PATCH 3/5] Fix dmd test failures --- test/compilable/extra-files/header2.di | 4 ++-- test/compilable/extra-files/header2i.di | 4 ++-- test/fail_compilation/fail183.d | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/compilable/extra-files/header2.di b/test/compilable/extra-files/header2.di index 9f469b51a55f..b46460f30e71 100644 --- a/test/compilable/extra-files/header2.di +++ b/test/compilable/extra-files/header2.di @@ -2,7 +2,7 @@ class C { } void foo(const C c, const(char)[] s, const int* q, const(int*) p); -void bar(in void* p); +void bar(scope const void* p); void f(void function() f2); class C2; void foo2(const C2 c); @@ -93,7 +93,7 @@ void foo11217()(auto ref int[] arr) void foo11217()(scope int[] arr) { } -void foo11217()(in int[] arr) +void foo11217()(scope const int[] arr) { } void foo11217()(inout int[] arr) diff --git a/test/compilable/extra-files/header2i.di b/test/compilable/extra-files/header2i.di index a8a1db04a7d9..d6672b89360f 100644 --- a/test/compilable/extra-files/header2i.di +++ b/test/compilable/extra-files/header2i.di @@ -4,7 +4,7 @@ class C void foo(const C c, const(char)[] s, const int* q, const(int*) p) { } -void bar(in void* p) +void bar(scope const void* p) { } void f(void function() f2); @@ -106,7 +106,7 @@ void foo11217()(auto ref int[] arr) void foo11217()(scope int[] arr) { } -void foo11217()(in int[] arr) +void foo11217()(scope const int[] arr) { } void foo11217()(inout int[] arr) diff --git a/test/fail_compilation/fail183.d b/test/fail_compilation/fail183.d index c43d377e9f92..c72a6d300503 100644 --- a/test/fail_compilation/fail183.d +++ b/test/fail_compilation/fail183.d @@ -3,7 +3,7 @@ TEST_OUTPUT: --- fail_compilation/fail183.d(10): Error: redundant attribute `const` fail_compilation/fail183.d(10): Error: redundant attribute `scope` -fail_compilation/fail183.d(11): Error: redundant attribute `in` +fail_compilation/fail183.d(11): Error: redundant attribute `scope const` --- */ From 0d4c724553018049c733c52ec47cc5d8722e668f Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Wed, 5 Feb 2020 16:07:35 +0100 Subject: [PATCH 4/5] Hack to infer scope without selecting it via the command-line --- src/dmd/func.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dmd/func.d b/src/dmd/func.d index c30c81f9276c..c2df18021ef1 100644 --- a/src/dmd/func.d +++ b/src/dmd/func.d @@ -1326,7 +1326,7 @@ extern (C++) class FuncDeclaration : Declaration flags |= FUNCFLAG.returnInprocess; // Initialize for inferring STC.scope_ - if (global.params.vsafe) + if (global.params.vsafe || true) flags |= FUNCFLAG.inferScope; } From e7a0e7f9567a34f034f67aad4bb8ca338266a10a Mon Sep 17 00:00:00 2001 From: Atila Neves Date: Wed, 5 Feb 2020 16:43:48 +0100 Subject: [PATCH 5/5] Non hacky way to get around issue 20362 --- src/dmd/func.d | 2 +- src/dmd/semantic3.d | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/dmd/func.d b/src/dmd/func.d index c2df18021ef1..c30c81f9276c 100644 --- a/src/dmd/func.d +++ b/src/dmd/func.d @@ -1326,7 +1326,7 @@ extern (C++) class FuncDeclaration : Declaration flags |= FUNCFLAG.returnInprocess; // Initialize for inferring STC.scope_ - if (global.params.vsafe || true) + if (global.params.vsafe) flags |= FUNCFLAG.inferScope; } diff --git a/src/dmd/semantic3.d b/src/dmd/semantic3.d index 1b7fa139014f..3e594aa341ae 100644 --- a/src/dmd/semantic3.d +++ b/src/dmd/semantic3.d @@ -456,8 +456,14 @@ private extern(C++) final class Semantic3Visitor : Visitor stc |= STC.scope_; } } - if (funcdecl.flags & FUNCFLAG.inferScope && !(fparam.storageClass & STC.scope_)) + + // infer scope for lambdas even without -preview=dip1000 + // See https://issues.dlang.org/show_bug.cgi?id=20362 + const isLambda = funcdecl.isFuncLiteralDeclaration; + + if ((funcdecl.flags & FUNCFLAG.inferScope || isLambda) && !(fparam.storageClass & STC.scope_)) stc |= STC.maybescope; + stc |= fparam.storageClass & (STC.in_ | STC.out_ | STC.ref_ | STC.return_ | STC.scope_ | STC.lazy_ | STC.final_ | STC.TYPECTOR | STC.nodtor); v.storage_class = stc; v.dsymbolSemantic(sc2);