diff --git a/src/dmd/parse.d b/src/dmd/parse.d index 16e430f94f7a..c0192f6de741 100644 --- a/src/dmd/parse.d +++ b/src/dmd/parse.d @@ -2864,7 +2864,8 @@ final class Parser(AST) : Lexer // Don't call nextToken again. } case TOK.in_: - stc = STC.in_; + // `in` now means `const scope` as originally intented + stc = STC.const_ | STC.scope_; goto L2; case TOK.out_: 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); 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/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_); 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` --- */