Skip to content

Conversation

dkorpel
Copy link
Contributor

@dkorpel dkorpel commented May 28, 2021

Continuation of #8076, but for dlang/dmd#12010 instead of dlang/dmd#10924

I'm still figuring out what to do with range functions like array, text and toCase. scope fails to be inferred for simple char[] cases, but putting scope on them forces every InputRange it's called on to be scope compatible, while a generic InputRange can escape its innards through global variables or Exceptions. Not that I want to support such ranges, but it would make transitioning to -dip1000 more diffcult for users, so it may be better to leave them be and use work-arounds for current Phobos functions that need them to be scope, like I did in std.getopt by replacing split (not scope compatible, returns array of slices) with splitter (lazy, scope compatible).

@dlang-bot
Copy link
Contributor

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

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 + phobos#8113"

@dkorpel
Copy link
Contributor Author

dkorpel commented Jul 7, 2021

This should be good to go now: I can now locally build Phobos' unittests with dlang/dmd#12010

I undid some of the scope annotations of Per's PR because they were only done to satisfy the requirement that pure functions always take scope arguments, which I argued against.

Many range functions don't have correct scope inference yet, so I replaced some static arrays in @safe unittests with arrays in static data. They can be enhanced to work with scope ranges later, for now it's important to fix dip1000 first

@CyberShadow CyberShadow removed their request for review July 7, 2021 11:19
Copy link
Contributor

@thewilsonator thewilsonator left a comment

Choose a reason for hiding this comment

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

Pardon my ignorance here

For a lazy version, see $(REF joiner, std,algorithm,iteration)
+/
ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, scope R sep)
ElementEncodingType!(ElementType!RoR)[] join(RoR, R)(RoR ror, R sep)
Copy link
Contributor

Choose a reason for hiding this comment

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

this removes scope I thought this PR was trying to add it, am I missing something?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Range functions should ideally infer scope based on empty(), popFront(), front(), copy constructors etc.
scope inference is not that good yet however (issue 20674) so sometimes scope is manually applied to help the compiler. With issue 20150 fixed, this scope R sep gives an error:

scope variable sep assigned to non-scope parameter r calling std.array.array!(Once).array

So the long term fix is to ensure scope inference works for both join and array, but that's an enhancement. For now it's important to get the dip1000 bug fix in.

Copy link
Contributor

Choose a reason for hiding this comment

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

Won't this break existing code if the inference fails?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All the accepts-invalid fixes for dip1000 are breaking changes. Luckily dip1000 is still experimental.

Copy link
Contributor

Choose a reason for hiding this comment

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

But these changes are neither specific to DIP1000 nor about actually invalid code. It would be better to first improve the inference s.t. there is no unecessary breakage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What code do you think would break without -preview=dip1000?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't have aspecific example ATM, will post one if I find a small example.
But we should strive to not break valid code. -dip1000 has existed for quite some time and is certainly used in the wild.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

dlang/dmd#12010 is going to break such dip1000 code in the wild undoubtedly, I just tested it on my own 37 KLOC dip1000 library and I had to add 3 scope annotations. Do you think we need a second switch preview=dip1000fixed?

Copy link
Contributor

Choose a reason for hiding this comment

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

Neither said nor implied that - some breakage will be unavoidable. I'm just concerned that these changes introduce a temporary regression that could be avoided by first improving the scope inference.

But the actual fallout might be neglegible given that your projects required minimal changes and buildkite passes as is.

See_Also:
$(LREF asAbsolutePath) which does not allocate
*/
string absolutePath(return scope string path, lazy string base = getcwd())
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

absoultePath calls chainPath(baseVar, path).array, and scope inference fails for .array currently

`Exception` if the specified _base directory is not absolute.
*/
string relativePath(CaseSensitive cs = CaseSensitive.osDefault)
(scope return string path, lazy string base = getcwd())
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

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

relativePath calls asRelativePath which takes input ranges, and scope inference fails there

@thewilsonator
Copy link
Contributor

This otherwise looks OK

@thewilsonator
Copy link
Contributor

Thanks for clearing that all up.

@thewilsonator
Copy link
Contributor

please rebase or force push to start CircleCI

@dkorpel dkorpel force-pushed the more-pure-scope branch 2 times, most recently from 9d930b0 to a94213e Compare July 8, 2021 19:35
@dlang-bot dlang-bot merged commit 9ec2419 into dlang:master Jul 11, 2021
@dkorpel dkorpel deleted the more-pure-scope branch July 11, 2021 13:35
void move(T)(ref T source, ref T target)
{
moveImpl(source, target);
moveImpl(target, source);
Copy link
Contributor

@nordlow nordlow Jul 11, 2021

Choose a reason for hiding this comment

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

Why the reversion of parameter order?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I probably should have made a comment in the source code as well

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.

6 participants