-
-
Notifications
You must be signed in to change notification settings - Fork 705
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 14478: support non-copyable elements in many range algorithms #8721
Conversation
|
Thanks for your pull request, @WebFreak001! Bugzilla references
Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub run digger -- build "master + phobos#8721" |
|
@WebFreak001 the testers are failing. Are you willing to push this to the finish line? |
|
thanks! |
|
Thank you! |
|
This PR results in issues at Weka with The cause of the problem: Testcase (https://d.godbolt.org/z/z6KMY6nYf): import std.range;
struct Handle {
int[5] entries;
void opAssign()(auto ref const(typeof(this)) that) const { }
}
const(Handle)[100] arr;
auto foo() {
return arr[0..5].retro;
}the problem is fixed by reverting the lines for retro. |
Aside from anything to do with the specific changes here, what does a |
It's used to enable assigning to a const(Handle!Block) as if it is a Handle!(const(Block)), and it's indeed writing to something outside the object. There could be better solutions, but "it worked" before... |
I'm not trying to argue against changing the Phobos code. I'm just trying to understand why anyone would be doing anything with a Regardless of the details of your code, you've clearly shown that |
Then let's keep the discussion on topic and not derail it, thanks. |
|
The |
|
https://issues.dlang.org/show_bug.cgi?id=24481
It's very relevant, because understanding why users are doing weird edge-case stuff can have a big impact on what we test for in Phobos and the way that algorithms are written. And in this case, the Weka code is doing something that plenty of folks are just going to assume is illegal.
As far as correctness goes, none of those functions should be using a move without verifying that it's legal first. They should probably all be changed to use a static if that checks whether a move compiles and use that if it is and do assignment otherwise. |
|
I'll have a PR for this in a bit. |
In an attempt make it so that non-copyable types worked with some of the functions in std/range/package.d, they were made to use moves instead of assignment, which broke the code for types which work with assignment but not moves (which affected the folks at Weka). The code checked for assignment but not whether move could be used, and that didn't change when the code was changed to use move, meaning that the checks didn't match what the code was actually doing. So, to support both the non-copyable types and the ones that can be assigned to but not moved to, this changes the code so that it uses a static if to check whether using move compiles, branching the code based on whether move works on not. If move works, it's used. If it doesn't, then assignment is used like used to be the case. So, in theory, the code that worked previously works again, and the newer functionality of being able to use non-copyable types with this code continues to work. Discussion here: dlang#8721
|
thank you! |
In an attempt make it so that non-copyable types worked with some of the functions in std/range/package.d, they were made to use moves instead of assignment, which broke the code for types which work with assignment but not moves (which affected the folks at Weka). The code checked for assignment but not whether move could be used, and that didn't change when the code was changed to use move, meaning that the checks didn't match what the code was actually doing. So, to support both the non-copyable types and the ones that can be assigned to but not moved to, this changes the code to use core.lifetime.forward which will move the argument if it can and assign otherwise. So ,the code that worked previously should work again, and the newer functionality of being able to use non-copyable types with this code should continue to work. Discussion here: dlang#8721
In an attempt make it so that non-copyable types worked with some of the functions in std/range/package.d, they were made to use moves instead of assignment, which broke the code for types which work with assignment but not moves (which affected the folks at Weka). The code checked for assignment but not whether move could be used, and that didn't change when the code was changed to use move, meaning that the checks didn't match what the code was actually doing. So, to support both the non-copyable types and the ones that can be assigned to but not moved to, this changes the code to use core.lifetime.forward which will move the argument if it can and assign otherwise. So ,the code that worked previously should work again, and the newer functionality of being able to use non-copyable types with this code should continue to work. Discussion here: #8721
same as #8714
code not fully covered