mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
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:
parent
a7d88984ce
commit
947de21c62
3 changed files with 52 additions and 1 deletions
|
@ -4045,6 +4045,7 @@ extern (C++) final class FuncExp : Expression
|
||||||
Type t = pto.type;
|
Type t = pto.type;
|
||||||
if (t.ty == Terror)
|
if (t.ty == Terror)
|
||||||
return cannotInfer(this, to, flag);
|
return cannotInfer(this, to, flag);
|
||||||
|
tf.parameterList[u].storageClass = tof.parameterList[u].storageClass;
|
||||||
tiargs.push(t);
|
tiargs.push(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
compiler/test/compilable/infer_stc.d
Normal file
51
compiler/test/compilable/infer_stc.d
Normal 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
|
||||||
|
}
|
|
@ -520,7 +520,6 @@ void test7705()
|
||||||
{
|
{
|
||||||
void foo1(void delegate(ref int ) dg){ int x=10; dg(x); }
|
void foo1(void delegate(ref int ) dg){ int x=10; dg(x); }
|
||||||
foo1((ref x){ pragma(msg, typeof(x)); assert(x == 10); });
|
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); }
|
void foo2(void delegate(int, ...) dg){ dg(20, 3.14); }
|
||||||
foo2((x,...){ pragma(msg, typeof(x)); assert(x == 20); });
|
foo2((x,...){ pragma(msg, typeof(x)); assert(x == 20); });
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue