Fix 11316: Infer storage class of parameters with function literals

This will allow improving functional style code by seamlessly
adding `ref` (or `in`) and having the compiler do the job.
This commit is contained in:
Geod24 2023-02-28 00:32:03 +01:00 committed by Nicholas Wilson
parent a7d88984ce
commit 947de21c62
3 changed files with 52 additions and 1 deletions

View file

@ -4045,6 +4045,7 @@ extern (C++) final class FuncExp : Expression
Type t = pto.type;
if (t.ty == Terror)
return cannotInfer(this, to, flag);
tf.parameterList[u].storageClass = tof.parameterList[u].storageClass;
tiargs.push(t);
}

View file

@ -0,0 +1,51 @@
/// Test storage class inference on delegate parameters
alias FPT = void function (in string, ref string, out string, scope string);
alias DGT = void delegate (in string, ref string, out string, scope string);
void f1 (FPT func)
{
string ro = "Hello World";
string ref_ = ro, out_ = ro;
func(ro, ref_, out_, ro);
}
void f2 (DGT func)
{
string ro = "Hello World";
string ref_ = ro, out_ = ro;
func(ro, ref_, out_, ro);
}
void test ()
{
f1((in_, ref_, out_, scope_) {
assert(in_ == "Hello World");
assert(in_ == scope_);
assert(in_ == ref_);
assert(out_ is null);
});
f2((in_, ref_, out_, scope_) {
assert(in_ == "Hello World");
assert(in_ == scope_);
assert(in_ == ref_);
assert(out_ is null);
});
}
// https://issues.dlang.org/show_bug.cgi?id=11316
void issue11316() {
void delegate(const int x) F0;
F0 = (const int x) {}; // OK
F0 = (x) {}; // OK
void delegate(in int x) F1;
F1 = (in int x) {}; // OK
F1 = (x) {}; // OK
void delegate(ref int x) F2;
F2 = (ref int x) {}; // OK
F2 = (x) {}; // Error
void delegate(out int x) F3;
F3 = (out int x) {}; // OK
F3 = (x) {}; // Error
}

View file

@ -520,7 +520,6 @@ void test7705()
{
void foo1(void delegate(ref int ) dg){ int x=10; dg(x); }
foo1((ref x){ pragma(msg, typeof(x)); assert(x == 10); });
static assert(!__traits(compiles, foo1((x){}) ));
void foo2(void delegate(int, ...) dg){ dg(20, 3.14); }
foo2((x,...){ pragma(msg, typeof(x)); assert(x == 20); });