dmd icon indicating copy to clipboard operation
dmd copied to clipboard

Implement Static Single Assignment (SSA) DIP

Open WalterBright opened this issue 3 weeks ago • 17 comments

https://github.com/WalterBright/documents/blob/master/final.md

WalterBright avatar Dec 02 '25 07:12 WalterBright

Thanks for your pull request, @WalterBright!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub run digger -- build "master + dmd#22171"

dlang-bot avatar Dec 02 '25 07:12 dlang-bot

Given that this is running up against existing test cases (failing), it'll need to go behind a preview switch until it's ready & approved.

rikkimax avatar Dec 02 '25 08:12 rikkimax

Ran into an unexpected problem. Using __traits(getLinkage, F) to transfer final to a delegate causes problems.

WalterBright avatar Dec 02 '25 08:12 WalterBright

I think I can fix it. Tomorrow!

WalterBright avatar Dec 02 '25 08:12 WalterBright

void main()
{
    final int[2] a;
    a[0]++; // no error
    final S s;
    s.i++; // no error
}

struct S
{
    int i;
}

The DIP says:

final applied to a declaration of a variable of struct type means the non-static fields of the struct are implicitly final, and cannot be modified after initialization.

It doesn't mention static arrays, but as they are values, the elements should be final IMO.

ntrel avatar Dec 02 '25 19:12 ntrel

@ntrel you're right

WalterBright avatar Dec 03 '25 08:12 WalterBright

Casting a pointer to final should probably be allowed in @system code. It currently errors:

    final int i = 3;
    int* pm = cast(int*) &i; // Error: cannot implicitly convert final `& i` to `int*`

ntrel avatar Dec 03 '25 10:12 ntrel

As final is local to a function, and does not leak out of it, being able to override it in a function is not needed (one can simply delete the final in that function). It is not so simple with const, which is why that can be overridden in a @system function.

WalterBright avatar Dec 03 '25 18:12 WalterBright

As final is local to a function

final can apply to a module scope variable too, and the user of that variable may not have write access to the module where it's defined. I suppose use const tempPtr = &finalVar; then cast away const (e.g. to pass to a non-const function parameter that a particular call doesn't write to).

ntrel avatar Dec 04 '25 21:12 ntrel

@ntrel yes you can do that in @system code. But you're no worse off if you didn't add the final.

WalterBright avatar Dec 04 '25 23:12 WalterBright

How does final interact with other types and storage classes?

Structs, arrays, noreturn, ref, etc.

ibuclaw avatar Dec 05 '25 14:12 ibuclaw

How does final interact with other types and storage classes?

All in the same way. Any final variable declaration prevents modification of the contents of the variable.

  • structs: protects the fields
  • classes: protects the reference to the class
  • static arrays: protects the array contents
  • dynamic arrays: protects the pointer/length
  • ref: protects the reference already, final is redundant here
  • out: same as ref
  • delegate: protects the function pointer and context pointer

WalterBright avatar Dec 06 '25 00:12 WalterBright

out: same as ref

I'm amending that to 'final' being applied to an out parameter should be an error.

WalterBright avatar Dec 06 '25 00:12 WalterBright

The behavior of all these cases is based on the idea that a final object should not be subject to modification after initialization.

WalterBright avatar Dec 06 '25 01:12 WalterBright

ref: protects the reference already, final is redundant here

When I tried this a few days ago, the final actually applied to the pointed-to data, and I think that is more useful. See https://forum.dlang.org/post/[email protected].

ntrel avatar Dec 06 '25 11:12 ntrel

@ntrel thanks I will look into that.

WalterBright avatar Dec 07 '25 01:12 WalterBright

As explained in the ng, I've put this on hold for the time being.

WalterBright avatar Dec 08 '25 23:12 WalterBright