opApply @safety

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jan 29 14:33:43 PST 2016


On 1/29/16 3:08 PM, Chris Wright wrote:
> On Fri, 29 Jan 2016 14:00:08 -0500, Steven Schveighoffer wrote:
>
>> On 1/29/16 12:44 PM, Chris Wright wrote:
>>> I want to create an opApply for a type.
>>>
>>> I've marked my code @safe, because everything I wrote was @safe. The
>>> body of opApply is @safe, but it calls a delegate that may or may not
>>> be @safe.
>>>
>>> How do I make it so I can iterate through this type safely and
>>> systemly?
>>
>> Likely an overload. Tag the delegate as being @safe or not.
>>
>> -Steve
>
> That's handy. It works. I can make it so someone can call:
> foo.opApply((i, k, v) @safe => 0);
> foo.opApply((i, k, v) @system => 0);
>
> And that works.
>
> However, if you have:
> @safe void bar() {
>    foreach(i, k, v; foo) {
>    }
> }
>
> the compiler complains:
>
> opapplysafe.d(12): Error: foo.opApply matches more than one declaration:
> opapplysafe.d(2):     @safe int(int delegate(int, string, string) @safe
> dg)
> and:
> opapplysafe.d(5):     @system int(int delegate(int, string, string)
> @system dg)
>
> Guess I'll file a bug.
>

Definitely seems like a bug.

As a workaround, you can name the opApply functions:

struct S
{
    int opApply(int delegate(int, string, string) @safe dg) @safe {...}
    int unsafeApply(int delegate(int, string, string) dg) {...}
}

foreach(i, k, v; foo.unsafeApply) {...}

though that's... ugly.

-Steve


More information about the Digitalmars-d-learn mailing list