Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix some of the more egregious aspects of 19961 #10035

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

thewilsonator
Copy link
Contributor

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @thewilsonator! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the annotated coverage diff directly on GitHub with CodeCov's browser extension
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

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 fetch digger
dub run digger -- build "master + dmd#10035"

Copy link
Contributor

@TurkeyMan TurkeyMan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right...

int i = 42;
auto dg1 = delegate void() immutable
{
i++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be an error, i is immutable in this scope.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is, this is a fail_compilation test.

int* p = &i;
auto dg2 = delegate int() const
{
i++; // successfully rejected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i is const in this scope.


auto dg3 = delegate int() inout
{
i++; // successfully rejected
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@TurkeyMan
Copy link
Contributor

TurkeyMan commented Jun 14, 2019

The error is misleading then; "cannot access mutable data i" ... i is immutable in that scope, so the error message is wrong?
The error would be that you can't increment an immutable variable...

What does pragma(msg, typeof(i)); in that scope print?

@thewilsonator
Copy link
Contributor Author

pragma(msg, typeof(i));

int, I haven't fixed that problem yet.

@PetarKirov
Copy link
Member

Can you rename test/fail_compilation/test19961.d back to test/fail_compilation/test15306.d? It's difficult to trace the changes that you made in the GitHub diff.

@thewilsonator
Copy link
Contributor Author

I could, but everything in that test case is wrong.

auto dg2 = delegate int() const
{
i++; // successfully rejected
//int j = *p; // incorrectly rejected
Copy link
Member

@PetarKirov PetarKirov Jun 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be fixed before the PR can be merged. I believe that if you are able to fix the root cause and change the type of the p inside the delegate it would automatically fix this as well ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that the context pointer's qualifiers are not applied at all to access from within the nested function. I'm probably going to end up deleting the entire loop and else branch, the comment of the cascaded nested function is a complete lie, i can modify fx even if it is pure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it simple the case that the context pointer is not qualified? It mustn't be, or the type checker would be freaking out everywhere. Wherever the function receives the Context* argument, if it swaps for qualified(Context)*, then everything should wring out naturally?

@PetarKirov
Copy link
Member

but everything in that test case is wrong.

In that case it's even more important for us to be able to track the changes that you made.

@WalterBright
Copy link
Member

WalterBright commented Jun 14, 2019

When referring to an issue, please link to it, like this: https://issues.dlang.org/show_bug.cgi?id=19961

Also, insert into bugzilla a link to this page.

@PetarKirov
Copy link
Member

PetarKirov commented Jun 14, 2019

You should also add a compilable test along the lines of:

// const should be able to access mutable and immutable alike, but not modify it:
int i = 42;
int* p = &i;
auto dg = delegate int() const
{
    static assert(!__traits(compiles, { i++; })); // correctly disallowed
    
    // For all outer variables V of type Q1(T) accessed through context
    // with qualifier Q2 do implicit qualifier conversion to Q1(Q2(T)),
    // where Q1(Q2) is the resulting qualifier according to the table in:
    // https://dlang.org/spec/const3.html#implicit_qualifier_conversions
    static assert(is(typeof(p) == const(int*)));

    return *p; // OK: implicit conversion from `const(int)` to `int`
};
assert(dg2() == i);

@PetarKirov
Copy link
Member

PetarKirov commented Jun 14, 2019

Also, insert into bugzilla a link to this page.

@WalterBright there's no need to do this manually anymore as the @dlang-bot will do this automatically if the commit message follows the right format (https://github.com/dlang/dlang-bot#nerdy-details).

@thewilsonator
Copy link
Contributor Author

Yes, but this PR doesn't fix this, so the dlang-bot didn't pick it up.

@PetarKirov
Copy link
Member

PetarKirov commented Jun 14, 2019

@thewilsonator check the regex in the link I posted above ;)

In other words, you can use "Issue 19961 - Fix some of the more egregious aspects".

@WalterBright
Copy link
Member

@ZombineDev it didn't, so I added the link myself.

@PetarKirov
Copy link
Member

PetarKirov commented Jun 14, 2019

@WalterBright it didn't because the commit message was not in the right format. If it was, it would.

@TurkeyMan
Copy link
Contributor

I'm surprised by the approach here; it looks like the capture code is hard-coding qualifier conversions, and all sorts of magic.
I don't think the capture needs to do anything special; assuming the capture produces a Context*, the function just needs to have its signature tweaked to receive a qualified(Context)* (same as if it was a regular this pointer), and then within the function the Context object and everything it refers to would correctly be const...?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants