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 20674, 23208, 23300 - improve scope inference #14492

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

dkorpel
Copy link
Contributor

@dkorpel dkorpel commented Sep 27, 2022

Remove the complex and broken eliminateMaybeScopes system for parameters, and use a simpler scheme for both parameters and local variables. When you assign va = v, then add a link from va to v and when va becomes return scope or notMaybeScope, then do the same for v.

It's not complete yet, I still need to go the other way and test more thoroughly, but I'm already opening a PR to get feedback from the test suite, and so that I can link to this central PR when making smaller PRs.

@dkorpel dkorpel added Review:WIP Work In Progress - not ready for review or pulling dip1000 memory safety with scope, ref, return labels Sep 27, 2022
@dlang-bot
Copy link
Contributor

dlang-bot commented Sep 27, 2022

Thanks for your pull request and interest in making D better, @dkorpel! 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 coverage diff by visiting the details link of the codecov check)
  • 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

Auto-close Bugzilla Severity Description
20674 enhancement [DIP1000] inference of `scope` is easily confused
23208 normal [dip1000] missing return scope inference after parameter assignment
23294 normal [dip1000] parameter to parameter assignment leads to incorrect scope inference
23300 normal std.array : array wrongly propagates scopeness of source

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#14492"

@@ -1105,7 +1105,7 @@ extern (C++) class VarDeclaration : Declaration
VarDeclaration lastVar; // Linked list of variables for goto-skips-init detection
Expression edtor; // if !=null, does the destruction of the variable
IntRange* range; // if !=null, the variable is known to be within the range
VarDeclarations* maybes; // maybeScope variables that are assigned to this maybeScope variable
VarDeclaration lifetimeParent; // the declaration with represents the lifetime of this variable, null = its own root
Copy link
Contributor

@nordlow nordlow Oct 5, 2022

Choose a reason for hiding this comment

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

Thank you for doing this. This, as far as the comment goes, seems much easier to reason about.

@nordlow
Copy link
Contributor

nordlow commented Oct 5, 2022

Will this refactoring make it easier to implement automatic scope inference of variables? Even including parameters of function templates? An idea Walter has approved of.

@dkorpel
Copy link
Contributor Author

dkorpel commented Oct 5, 2022

Will this refactoring make it easier to implement automatic scope inference of variables?

This is not a refactoring, it is the new implementation of automatic scope inference on function parameters.

Currently scope parameter inference fails in two ways:

  • On assignment to another parameter: it's too permissive; doesn't consider relative lifetime (23294) and neglects return scope (23208)
  • On assignment to a local variable: it's pessimistic, it gives up immediately (20674)

The new system treats both the same, and puts every 'maybe scope' variable in a set. When one maybe scope variable is assigned to another, it joins the two sets. As soon as any of them is inferred return scope or considered 'not maybe scope', then the set collapses and all variables in it become return scope / 'not maybe scope'. This system passed the test suite in my first implementation using an array of neighbors, but I'm now in the process of switching to a Disjoint-set data structure and currently it's red again.

The new system is still a bit pessimistic, but:

  • It's relatively simple
  • It has almost linear time complexity (Walter does not want to do Data Flow Analysis in the frontend because it's slow)
  • It fixes the most common reason of scope inference failure: assignment to a temporary variable.

Even including parameters of function templates?

Scope inference of parameters is only enabled in templates, nested functions and auto returning functions.

@nordlow
Copy link
Contributor

nordlow commented Oct 5, 2022

src/dmd/frontend.h needs update as per https://auto-tester.puremagic.com/show-run.ghtml?projectid=1&runid=5352408&isPull=true.

To update frontend.h and fix this error, run the following command:

../../generated/build cxx-headers-test AUTO_UPDATE=1

@dkorpel
Copy link
Contributor Author

dkorpel commented Oct 5, 2022

src/dmd/frontend.h needs update

I know, see the WIP tag ;)

I'm currently focusing on making my test case for return scope inference after assignment pass.

@nordlow
Copy link
Contributor

nordlow commented Oct 5, 2022

I'm currently focusing on making my test case for return scope inference after assignment pass.

Ahh, sorry.

@rikkimax
Copy link
Contributor

This work appears to be much more important than just scope inference.

Having a way to tie a variable to its lifetime root, means we have a way to ensure the correct order of destruction of memory; this means we can very easily do a "borrow checker" with only the owner being able to be destroyed automatically. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Status: In Progress
Status: In Progress
Development

Successfully merging this pull request may close these issues.

4 participants