Recursion and attribute inference

Dennis dkorpel at gmail.com
Thu Nov 3 16:42:05 UTC 2022


On Wednesday, 2 November 2022 at 22:01:24 UTC, Paul Backus wrote:
> I'm inclined to say the implementation is right, since the code 
> does not actually violate memory safety.
>
> According to [the latest D Foundation meeting summary][1], 
> Dennis Korpel is looking into making `@safe` inference work 
> properly for recursive functions, so it's possible that this 
> limitation will be lifted entirely in the future.
>
> [1]: 
> https://forum.dlang.org/thread/jzqabfjmdwveeatpdklj@forum.dlang.org

Right.

When a function calls itself directly, attribute checks for that 
call are ignored.
However, when there's one or more functions in between, the 
reasoning goes "I'm calling a function that can't finish 
attribute inference right now, so conservatively assume all 
attributes failed to infer to be on the safe side." It seems the 
specification was modified to document this shortcoming of the 
implementation.

I wish we could simply assume all attributes were inferred, which 
would make this work:

```D
void fun1()() { fun2(); }
void fun2()() { fun1(); }

void main() @safe pure nothrow @nogc
{
     fun1(); // currently fails
}
```

But here's a more tricky case:
```D
@system void systemFunc();

void fun1()()
{
     alias T = typeof(fun2());
     systemFunc();
}

void fun2()()
{
     fun1();
}

void main0() @system
{
     fun1();
}

void main() @safe
{
     fun2(); // not system!
}
```

The compiler analyzes `fun1`, then `fun2`, and then needs to 
decide if the call to `fun1` is safe.
If it assumes 'yes', then later when it sees the call to 
`systemFunc()`, it would need to go back and make `fun2()` 
@system, and re-analyze the function body of `fun1` where `T` is 
now a @system function.

DMD is not suited to do this kind of backtracking, and that would 
potentially be very slow as well, so this probably won't be fixed 
in the general case.

However, in the absence of typeof() and other function type 
dependencies, a list of callees for each function can be 
maintained to solve the most common case of mutual function 
dependencies through simple function calls.



More information about the Digitalmars-d mailing list