dmd icon indicating copy to clipboard operation
dmd copied to clipboard

Fix 13567 - Infer attributes for private functions

Open Geod24 opened this issue 5 years ago • 8 comments

💥

Needs https://github.com/dlang/druntime/pull/3214 and maybe others (DMD tests pass on my machine). Pre-approved by @WalterBright in 2015 and I doubt he changed his mind on having more inference since.

Opening as draft just to give some time for feedback. I think it's one of those things that everyone wants, but if anyone can come up with ways to break it, it's welcome. I'm thinking about public aliases & the like.

Geod24 avatar Sep 21 '20 07:09 Geod24

dlang/druntime#3214 merged

thewilsonator avatar Sep 22 '20 06:09 thewilsonator

I recall Walter mentioning inference of constness of member functions aswell a couple of years ago.

nordlow avatar Sep 22 '20 07:09 nordlow

Rebased in order to restart the CI pipelines.

PetarKirov avatar Sep 22 '20 21:09 PetarKirov

There seem to be at least two bugs in the current implementation: Something to do with package, and something with template. Looking into it.

Geod24 avatar Sep 26 '20 20:09 Geod24

Of course the issue is forward references. Currently an auto function A calling another function B will trigger B's semantic3 which is needed to infer attributes. If A and B are both auto and call each other, such as the following:

private auto myFunc (int recurse)
{
    return 1 + (recurse ? foo(recurse - 1) : 0);
}

private auto foo (int recurse)
{
    return 1 + (recurse ? myFunc(recurse - 1) : 0);
}

void main () @safe pure nothrow @nogc
{
    assert(myFunc(41) == 42);
}

You'll get this lovely error message:

test.d(8): Error: forward reference to inferred return type of function call `myFunc(recurse - 1)`

Which you won't with non-auto functions at the moment. Just giving them the auto treatment would add new forward references, which is not acceptable, so this isn't going to be easy.

Geod24 avatar Sep 26 '20 22:09 Geod24

Which you won't with non-auto functions at the moment.

@Geod24 How about we do something like this: if we end up having a forward reference error in the process of automatically inferring attributes for a private non-auto function, we simply stop inferring and the user has to manually annotate it?

RazvanN7 avatar Jan 08 '21 10:01 RazvanN7

No I don't think that's wise. I'd rather delay this until we have time for a proper fix than put another half-baked feature in the compiler. Not to mention, a trial-and-error approach like this comes with its own downsides (namely potentially superfluous codegen and forward references issues) and would be quite brittle IMHO.

Geod24 avatar Jan 09 '21 06:01 Geod24

A proper fix would require something along the lines of: check the function body for safety, purity, nogc, nothrow without considering function calls (during this pass you can create an array of references to functions that are called), then do the same for all the function calls (creating a call graph in the process), walk the call graph and appropriately update the attributes. It's an interesting problem, however, it feels that such complicated machinery is not going to be accepted.

RazvanN7 avatar Jan 09 '21 09:01 RazvanN7