Uncallable delegates

FeepingCreature feepingcreature at gmail.com
Wed May 13 02:19:04 UTC 2026


On Tuesday, 12 May 2026 at 11:13:15 UTC, Dukc wrote:
> Now, there are some practically unavoidable corner cases where 
> such unsafe delegates can be created. Consider an abstract 
> class:
>
> ```D
> class A
> {   abstract @safe void foo() const;
> }
> ```
>
> If you convert an object of `A` to `const(A)`, this could be 
> problematic, because the concrete class of the object could be
>
> ```D
> class B : A
> {   int field;
>     @safe void delegate() del;
>     @safe void increment(){field++;}
>     @safe void foo() const {del();}
> }
> ```
>
> and `del` might point `increment` and context to the object 
> itself. The result would be that calling `foo` mutates the 
> object in violation of the `const` qualification.
>

I think this is actually an interesting case that is unrelated to 
the examples in the DIP? The question there is if the delegate 
belongs to the caller or the callee. For instance, nobody would 
argue that this code is a violation of constness:

```
class A {
   int x;
   int foo() const;
}
auto a = new A;
if (a.foo() == 0) {
   a.x = 5;
}
```
That is, because the caller holds a non-const reference to `a`, 
it is allowed to perform non-const operations on `a`. The 
question then is, if passing a delegate to a const method or 
handing it to a const class, makes the delegate "an effect of the 
method" if called, such that the delegate violates constness; or 
if it's semantically "an effect of the caller", such that the 
action is "performed by the caller, who holds a mutable 
reference."

To me the most debatable case is

```
class A {
     int x;
     int foo(void delegate() dg) const { dg(); }
}
auto obj = new A;
obj.x = 3; // we can unquestionably mutate obj
auto dg = { obj.x = 4; }; // we can unquestionably wrap up the 
ability to mutate obj
obj.foo(dg); // can we pass it to a method that is nominally 
const on obj?
```

I agree with the DIP, as far as I understand it, but this example 
does not seem like it is covered by it, and I don't think it 
should be either. Am I missing something?


More information about the dip.development mailing list