Why use a DFA instead of DIP1000?

Dennis dkorpel at gmail.com
Tue Sep 16 20:00:06 UTC 2025


On Tuesday, 16 September 2025 at 17:09:18 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
> Okay fine.
> Bugzilla is down, so I can't look through the WONTFIX's and I'm 
> not going to go hunting on the N.G. learn forum.

Thanks a lot! I don't need many, I just need 1 good one, so you 
delivered already.

> I can spot: https://github.com/dlang/dmd/issues/19679
> You tried to fix it and haven't in the past. With a DFA for the 
> infrastructure, that wouldn't be possible to have existed.
>
> Another example from you for the above: 
> https://github.com/dlang/dmd/issues/18113

The escape checking logic for assigning a parameter with scope 
inference to a local variable is bad, definitely. Like you say 
I've been working on a fix which remains unfinished because:

- dmd/escape.d is full of duplicated spaghetti logic (though it 
has improved)
- The test suite and buildkite projects rely on existing quirks
- dip1000 by default is no longer a priority issue, so I shifted 
work to more important stuff

Unless you consider my refactoring and WIP solution a 
rewrite/DFA, I wouldn't say a DFA rewrite is *required*, but I 
certainly was tempted to throw out dmd/escape.d and rewrite that 
hot mess from scratch 🙂.

> Here is a ticket, with a comment from you showing why DIP1000 
> needs to be lint level attribution. 
> https://github.com/dlang/dmd/issues/20302#issuecomment-2542028404

You haven't defined what "lint level attribution" means, but that 
issue would be solved if we add inferred `scope` parameters to a 
function type's mangle in a next edition so I don't see how this 
issue necessitates a rewrite/DFA.

> If it isn't you break things like the .di generator since it 
> runs before semantic.

The .di generator also needs to run semantic to emit correct 
inferred function attributes, that change doesn't require 
rewriting DIP1000 / adding DFA.

> It also results in issues like:
> https://github.com/dlang/dmd/issues/19853

That issue is invalid, see closing comment.

> Another example where DIP1000 loses track of lifetimes: 
> https://github.com/dlang/dmd/issues/18153
> To fix that you would need to keep track of a stack of 
> lifetimes, with full knowledge of the variables in a function 
> signature. All things a DFA would be good at.

I haven't studied that issue, but I suspect it has more to do 
with the internal opApply rewrite than a lack of DFA.

> To model this across function boundaries, we need to add an 
> escape set in the CFG of blockexit and on the function 
> declaration.

How would you throw a `scope` Exception across function 
boundaries? I can't picture that being valid but I haven't 
thought very hard.

---

So far, the most representative issue is definitely 
https://github.com/dlang/dmd/issues/19679.

I agree that a rewrite using a DFA engine would be sufficient to 
handle that case, I just don't think it's necessary. And that's 
because I'm noticing a theme in the code snippets you use to 
showcase your DFA engine vs. the reduced code snippets from the 
bug reports you just listed. Notice how unlike DFA examples, the 
DIP1000 bugs are not about asserts, if-statements or loops. The 
problematic code almost always exists inside the same basic 
block. That's why I think considering a function's control-flow 
graph is currently overkill for DIP1000.



More information about the Digitalmars-d mailing list