<div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 28 Aug 2024 at 20:11, Dennis via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wednesday, 28 August 2024 at 08:59:49 UTC, Manu wrote:<br>
> Oh wow... that's bad. Is there any plan to fix this?<br>
<br>
I want to, but with dmd's current architecture, I don't know how. <br>
The tricky case is:<br>
<br>
```D<br>
// example of @safe inference, but the same applies to pure <br>
nothrow and @nogc<br>
<br>
void systemFunc() @system;<br>
<br>
void fun1()()<br>
{<br>
fun2();<br>
systemFunc();<br>
}<br>
<br>
void fun2()()<br>
{<br>
fun1();<br>
}<br>
<br>
void main0() @system<br>
{<br>
fun1();<br>
}<br>
<br>
void main1() @safe<br>
{<br>
fun2(); // should error<br>
}<br>
```<br>
<br>
fun1 gets analyzed first, which gets interrupted when it sees the <br>
call to fun2.<br>
Then fun2 gets analyzed, but that sees a call to fun1, which at <br>
that point is still in the process of inferring attributes. The <br>
current implementation gives up here and infers fun2 as `@system`.<br>
<br>
So I tried replacing that pessimistic assumption with an <br>
optimistic assumption, but in this case, `fun1` will turn out to <br>
be `@system` because of the `systemFunc()` call. But at the time <br>
`fun2` ends its analysis, this is completely unknown. Until <br>
`fun1` ends its analysis, the needed information isn't there.<br>
<br>
I could start by inferring `fun2` as `@safe` and then retract <br>
that once `fun1` finishes analysis, but currently, the compiler <br>
assumes a function type to be final after its body was analyzed, <br>
so mutating the type later is going to mess up things.<br>
<br>
So without re-architecturing dmd's semantic analysis, I don't see <br>
a way out.<br></blockquote><div><br></div><div>I reckon while parsing a function X, you could gather any evidence available that invalidates the inference, and in lieu of any invalidation when you encounter Y that's not itself resolved, place a token on X that it's waiting on Y (and another token that it's waiting on Z, etc), then also place a token on Y and Z that says when it's finished it's own resolution it should poke the result back to X.<br></div><div>What will happen then is Y may run inference and be invalidated, in which case it reports the invalidation result back to X, and that may invalidate a cascade of pending inferences... or it may itself not be finalised waiting optimistically on the inference of X (or some other cycle).<br></div><div>At the end when everything's had a go, all outstanding tokens must be involved in optimistic cycles since there was nothing in any of those functions that invalidated their inferences; and since they're all outstanding on an optimistic cycle, then I think they naturally all satisfy eachother in the optimistic case. So just close out all outstanding tokens in the optimistic case... does that sound right?<br></div></div></div>