-
Notifications
You must be signed in to change notification settings - Fork 308
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
Avoid re-borrowing in multislice! macro #692
Conversation
47787ca
to
dd5ef0a
Compare
What is the error message if a user forgets the explicit reborrow? |
Checked it out with #[test]
fn test_multislice_intersecting() {
assert_panics!({
let mut arr = Array2::<u8>::zeros((8, 6));
multislice!(arr, mut [3, ..], [3, ..]);
}); The compiler spits out:
It's a bit oscure - anything we could do to make it less so? |
The old implementation always called `.view_mut()` on the input array, which meant that it was not possible to use `multislice!` to split an `ArrayViewMut` instance into pieces with the same lifetime as the original view. Now, `multislice!` uses `ArrayViewMut::from()` instead so that this works. The primary disadvantage is that an explicit borrow is necessary in many cases, which is less concise. Closes rust-ndarray#687.
dd5ef0a
to
8a51ff9
Compare
I think forcing the explicit borrow is potentially a good thing, as it makes the first parameter work as if it was a regular generic function call parameter, with fewer hidden behaviours. The error message is unfortunate, especially since the span of the error is the whole macro call instead of just the The best I can come up with is to shift the burden further towards the user and remove the implicit
|
Alternatively, we could revert the change in the macro back to calling |
Having a generic solution that will move or autoref as needed sounds tempting, but adding an extra trait just for that is less so. What we know is that it needs to be a method call to enable contextual autoref or not, and that it could be duck typed (Array and ArrayViewMut could have different same-named methods etc) |
I don't have a strong opinion about it - I don't decide. One could have the explicit borrow or adding methods to make it transparent. Methods doesn't seem easy to do well, either. Third option would be to provide a way to change how the conversion to view is done via some optional syntax in the macro. |
I agree that the span of the error message being the whole macro call instead of just the array isn't great. The following give error messages with a span of the whole macro: let mut view: $crate::ArrayViewMut<_, _> = $arr.into();
let mut view: $crate::ArrayViewMut<_, _> = ::std::convert::Into::into($arr);
let mut view: $crate::ArrayViewMut<_, _> = ::std::convert::From::from($arr);
let mut view: $crate::ArrayViewMut<_, _> = $crate::convert_into_arrayviewmut($arr); // where `convert_into_arrayviewmut` is a function with a parameter of type `impl Into<ArrayViewMut<'a, A, D>>`
let mut view = $crate::ArrayBase::view_mut(&mut $arr); while the following give error messages with a span of just the array argument: let mut view: $crate::ArrayViewMut<_, _> = $arr;
let mut view: $crate::ArrayViewMut<_, _> = $arr.view_mut(); So, it seems like non-trait method calls using dot notation or requiring the input to be Here are the options that I see:
I like options 1 and 2 pretty well. The semantics of option 3 are too confusing IMO. From the user's perspective, option 4 is really nice (no macros other than |
Speaking purely from an API perspective, I feel option 4. significantly improves what we have right now. |
Alternative 2 sounds like something we can do for 0.13 or 0.13.1, and alternative 4 sounds cool of course, but there is no rush and it can happen if someone has time to write it(?) |
Awesome. I prefer smooth evolution when not terribly hard to do so, deprecations when possible. So for example here multislice! Can be a deprecated shim for a new method, even if not a perfect shim? How to weigh the importance of deprecations is usually about gauging the number of users it impacts and how easy it is to understand and fix the break. |
Since So, I'd prefer to remove |
Oh sounds good. (I'm sorry I didn't realize multislice hasn't been released yet.) Another reason we should get the release out of the door. We shouldn't need to rewrite features before we premiere them :) |
The old implementation always called
.view_mut()
on the input array, which meant that it was not possible to usemultislice!
to split anArrayViewMut
instance into pieces with the same lifetime as theoriginal view. Now,
multislice!
usesArrayViewMut::from()
instead so that this works. The primary disadvantage is that an explicit borrow is necessary in many cases, which is less concise.Closes #687.