Uncallable delegates

Timon Gehr timon.gehr at gmx.ch
Wed Jun 17 10:16:45 UTC 2026


On 6/16/26 23:18, Walter Bright wrote:
> On 5/16/2026 12:20 AM, Timon Gehr wrote:
>> The best I can do right now is show you that the delegate type 
>> checking is different from classes:
>>
>> ```d
>> @safe:
>> struct T{
>>      int* delegate() dg;
>>      int* q;
>> }
>> T foo(){
>>      auto x = new int(2);
>>      auto dg = ()=>x;
>>      return T(dg,x);
>> }
>> void main(){
>>       const ps = foo();
>>       static assert(is(typeof(ps.dg)==const));
>>       auto p = ps.dg();
>>       static assert(is(typeof(p)==int*)); // `const` removed
>> }
>> ```
> 
> Instrumenting the example:
> 
> ```d
> @safe:
> struct T{
>       int* delegate() dg;
>       int* q;
> }
> T foo(){
>       auto x = new int(2);
>       auto dg = ()=>x;
>       return T(dg,x);
> }
> void main(){
>        const ps = foo();
>        pragma(msg, typeof(foo()));   // T
>        pragma(msg, typeof(ps));      // const(T)
>        pragma(msg, typeof(ps.dg));   // const(int* delegate() @safe) 
> DING DING
>        pragma(msg, typeof(ps.dg())); // int*
>        pragma(msg, typeof(ps.q));    // const(int*)
> }
> ```
> DING DING here's what's happening. The `const` is not turning the return 
> type of the delegate into `const`. There is no way for the type system 
> to look at a delegate type and determine if a const should be applied to 
> the return value or not, because the type system does not have access to 
> the delegate implementation.
> 
> I don't know how this might be resolved other than disallowing `const` 
> being applied to a delegate, which seems rather drastic.

Applying `const` to a delegate is fine. Calling a delegate that may 
require a mutable context with a `const` context is not. You can't pass 
a `const` argument with indirections to a mutable parameter. Except that 
for delegates, this is currently not enforced. Dukc's DIP fundamentally 
just proposes consistently enforcing this basic rule.

However, the call type checking and implicit conversion rules also 
should take into account that we know that the context had the correct 
type and qualifier when the delegate was initially created. Without this 
observation, it would be consistent to reject _all_ delegate calls.


More information about the dip.development mailing list