Struggling to implement parallel foreach...

Timon Gehr timon.gehr at gmx.ch
Tue Jun 18 14:07:46 UTC 2019


On 18.06.19 15:24, Timon Gehr wrote:
> On 18.06.19 14:00, Nicholas Wilson wrote:
>> On Tuesday, 18 June 2019 at 00:17:06 UTC, Timon Gehr wrote:
>>> Unfortunately I have another paper deadline in a few weeks, but maybe 
>>> I can set aside a few weekends this summer to try to fix function 
>>> qualifiers.
>>
>> I intend to beat you to it :)
>> ...
> 
> Great. :)
> 
>> Suleyman Sahmi has located where things go right for the struct 
>> case[1], so it shouldn't be too hard to manufacture a fix for the 
>> closure case.
>>
>> [1]: 
>> https://github.com/dlang/dmd/blob/f455995f234a2091c4482bff222a2977dbfa186b/src/dmd/expressionsem.d#L885-L886 
>>
> 
> I believe it might be easier to locate where things go right for 
> `shared` and `immutable` capturing and fix the logic there. I provide 
> tests below.
> 
> Note that a few missing checks and const-promotions when capturing are 
> not the only issue with nested function qualifiers. If the following 
> isses are fixed, we should be in pretty good shape (but probably I 
> forgot about something):
> 
> ...

In fact I did.

7. Local function calls need to be checked as if they were delegate 
captures.

The general rule is that the code

void fun(){
     void bar()qualifiers1{ ... }
     void foo()qualifiers2{
         bar();
     }
}

should compile exactly if the following code compiles:

void fun(){
     void bar()qualifiers1{ ... }
     qualifiers2 dg=&bar; // conversion always ok
     void foo()qualifiers2{
         dg(); // capturing of variable 'dg' always ok, but call may not be
     }
}

This yields a simple way to implement the check. Tests:

void fun(inout(int)*){
     void bar(){}
     void barc()const{}
     void bari()immutable{}
     void bars()shared{}
     void barsc()shared const{}
     void barw()inout{}
     void barsw()shared inout{}
     void barcw()const inout{}
     void barscw()shared const inout{}
     void foo(){
         bar(); // ok
         barc(); // ok
         bari(); // ok
         bars(); // ok
         barsc(); // ok
         barsw(); // ok
         barcw(); // ok
         barscw(); // ok
     }
     void fooc()const{
         bar(); // currently ok, shouldn't compile
         barc(); // ok
         bari(); // ok
         bars(); // currently ok, shouldn't compile
         barsc(); // ok
         barsw(); // currently ok, shouldn't compile
         barcw(); // ok
         barscw(); // ok
     }
     void fooi()immutable{
         bar(); // currently ok, shouldn't compile
         barc(); // currently ok, shouldn't compile
         bari(); // ok
         bars(); // currently ok, shouldn't compile
         barsc(); // currently ok, shouldn't compile
         barsw(); // currently ok, shouldn't compile
         barcw(); // currently ok, shouldn't compile
         barscw(); // currently ok, shouldn't compile
     }
     void foos()shared{
         bar(); // currently ok, shouldn't compile
         barc(); // currently ok, shouldn't compile
         bari(); // ok
         bars(); // ok
         barsc(); // ok
         barsw(); // ok
         barcw(); // currently ok, shouldn't compile
         barscw(); // ok
     }
     void foosc()shared const{
         bar(); // currently ok, shouldn't compile
         barc(); // currently ok, shouldn't compile
         bari(); // ok
         bars(); // currently ok, shouldn't compile
         barsc(); // ok
         barsw(); // currently ok, shouldn't compile
         barcw(); // currently ok, shouldn't compile
         barscw(); // ok
     }
     void foow()inout{
         bar(); // currently ok, shouldn't compile
         barc(); // currently ok, shouldn't compile
         bari(); // ok
         bars(); // currently ok, shouldn't compile
         barsc(); // currently ok, shouldn't compile
         barsw(); // ok
         barcw(); // ok
         barscw(); // ok
     }
     void foosw()shared inout{
         bar(); // currently ok, shouldn't compile
         barc(); // currently ok, shouldn't compile
         bari(); // ok
         bars(); // currently ok, shouldn't compile
         barsc(); // currently ok, shouldn't compile
         barsw(); // ok
         barcw(); // currently ok, shouldn't compile
         barscw(); // ok
     }
     void fooscw()shared const inout{
         bar(); // currently ok, shouldn't compile
         barc(); // currently ok, shouldn't compile
         bari(); // ok
         bars(); // currently ok, shouldn't compile
         barsc(); // currently ok, shouldn't compile
         barsw(); // currently ok, shouldn't compile
         barcw(); // currently ok, shouldn't compile
         barscw(); // ok
     }
}


More information about the Digitalmars-d mailing list