dmd icon indicating copy to clipboard operation
dmd copied to clipboard

allow ref on locals, globals, and statics

Open WalterBright opened this issue 1 year ago • 14 comments
trafficstars

Implementation of the proposal discussed in the n.g.:

https://www.digitalmars.com/d/archives/digitalmars/dip/development/First_Draft_ref_For_Variable_Declarations_74.html

WalterBright avatar Apr 30 '24 06:04 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#16428"

dlang-bot avatar Apr 30 '24 06:04 dlang-bot

are these such refs implicitly scope`?

Yes.

WalterBright avatar Apr 30 '24 07:04 WalterBright

Good to hear. Please add a fail_compilation (e.g. to diag9679.d) that tests that.

thewilsonator avatar Apr 30 '24 07:04 thewilsonator

Please add a fail_compilation (e.g. to diag9679.d) that tests that.

done.

WalterBright avatar Apr 30 '24 07:04 WalterBright

Cybershadow/DAutoTest gives no indication why it failed.

WalterBright avatar May 01 '24 02:05 WalterBright

As always , scroll to the bottom and work your way back up:

object.Exception@../tools/changed.d(256): Changelog entries should consist of one title line, a blank separator line, and a description.

thewilsonator avatar May 01 '24 02:05 thewilsonator

@thewilsonator I did scroll through it, but did not see that message, lost in the thousands of lines of output. Thanks for finding it for me!

WalterBright avatar May 01 '24 02:05 WalterBright

@ntrel it's the same as the way ref is used in any other context. Same semantics.

WalterBright avatar May 01 '24 17:05 WalterBright

@ntrel it's the same behavior as:

void foo(ref int x);
void bar(ref int y)
{
    foo(y);
}

WalterBright avatar May 02 '24 18:05 WalterBright

This is ready to go now.

WalterBright avatar May 02 '24 18:05 WalterBright

We should wait, the DIP has not even been submitted, let alone reviewed by the wider community.

thewilsonator avatar May 03 '24 10:05 thewilsonator

the DIP has not even been submitted, let alone reviewed by the wider community

That's what https://www.digitalmars.com/d/archives/digitalmars/dip/development/First_Draft_ref_For_Variable_Declarations_74.html is for.

WalterBright avatar May 03 '24 18:05 WalterBright

please don't merge yet

JohanEngelen avatar Jun 24 '24 14:06 JohanEngelen

This requires a lot more tests, not just error diagnostic testing. A lot of things can go wrong in implementation, so please be extensive in testing. Certainly all examples from the DIP should be tested, and things like:

int global;

ref int foo() { return global; }

void main() {
    auto i = foo();
    i = 1;
    assert(global == 0);
}

JohanEngelen avatar Jun 24 '24 15:06 JohanEngelen

Some things I found while testing:

ref can currently violate immutable by aliasing a mutable variable

void main()
{
    int x = 3;
    immutable ref int xr = x; // accepted!
    assert(xr == 3);
    x++;
    assert(xr == 3); // fails, immutable `xr` changed
}

ref can bind to rvalues and escape references to the stack this way

ref int escape() @safe
{
    ref int x = 4; // accepted!
    return x; // accepted!
}

dkorpel avatar Jul 18 '24 11:07 dkorpel

Perhaps add a -preview switch for this until it's stable enough? Then we can fix bugs separately as they come up.

ntrel avatar Jul 18 '24 19:07 ntrel

I tried to rebase it, but it got all fouled up by the refactoring done to escape.d. Sigh.

WalterBright avatar Jul 21 '24 18:07 WalterBright

I tried to rebase it, but it got all fouled up by the refactoring done to escape.d. Sigh.

You can just remove all changes this PR does to escape.d, it's already accomodating ref variables now.

dkorpel avatar Jul 21 '24 18:07 dkorpel

ref can bind to rvalues and escape references to the stack this way

There's already a test for that in diag9679.d. Like I said, the refactor means I have to go back through and refigure out how to implement it.

WalterBright avatar Jul 21 '24 19:07 WalterBright

There's already a test for that in diag9679.d. Like I said, the refactor means I have to go back through and refigure out how to implement it.

You just have to check that the initializer is an lvalue in dsymbolsem, escape.d works fine currently no?

dkorpel avatar Jul 21 '24 19:07 dkorpel

@JohanEngelen that example isn't part of the dip https://github.com/WalterBright/documents/blob/984374ca885e1cb10c2667cf872aebc13b4c1663/varRef.md

So I'm not sure what you're looking at?

WalterBright avatar Jul 23 '24 00:07 WalterBright

Perhaps add a -preview switch for this until it's stable enough?

As this is additive, and doesn't change existing code, it isn't necessary.

WalterBright avatar Jul 23 '24 02:07 WalterBright

@JohanEngelen that example isn't part of the dip https://github.com/WalterBright/documents/blob/984374ca885e1cb10c2667cf872aebc13b4c1663/varRef.md

So I'm not sure what you're looking at?

My point was to add the examples from the dip and add more. The example I gave is something that seems obvious but prevents bugs in the implementation where auto infers ref (it shouldn't).

JohanEngelen avatar Jul 23 '24 18:07 JohanEngelen

@JohanEngelen the language never infers storage class, but I put your example in the test suite anyway.

I don't think it needs more, after all, ref is used in several other contexts and has been pretty thoroughly debugged.

WalterBright avatar Jul 23 '24 20:07 WalterBright

A big reason why there are still so many bugs and regressions in the compiler is because tests are so scarce. The functionality says: "ref can now be applied to local, static, extern, and global variables". Four categories of variables, half of which don't even have a single test case...

JohanEngelen avatar Jul 24 '24 16:07 JohanEngelen

Yep, and as I already predicted: https://issues.dlang.org/show_bug.cgi?id=24729

JohanEngelen avatar Aug 29 '24 06:08 JohanEngelen