Skip to content

IntoNdProducer for &mut &mut ArrayBase #625

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

Closed
wants to merge 1 commit into from

Conversation

termoshtt
Copy link
Member

Objective

make the following code works

fn zip_ref_ref<Sa, Sb, D: Dimension>(mut a: &mut ArrayBase<Sa, D>, b: &ArrayBase<Sb, D>)
where Sa: DataMut<Elem = f64>,
      Sb: Data<Elem = f64>
{
    azip!(mut a, b in { *a = 2.0*b });
}

Problem

Current master reports an error:

error[E0277]: the trait bound `&mut &mut ndarray::ArrayBase<Sa, D>: ndarray::zip::NdProducer` is not satisfied
 --> tests/zip.rs:8:5
  |
8 |     azip!(mut a, b in { *a = 2.0*b });
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ndarray::zip::NdProducer` is not implemented for `&mut &mut ndarray::ArrayBase<Sa, D>`
  |
  = help: the following implementations were found:
            <ndarray::ArrayBase<ndarray::ViewRepr<&'a A>, D> as ndarray::zip::NdProducer>
            <ndarray::ArrayBase<ndarray::ViewRepr<&'a mut A>, D> as ndarray::zip::NdProducer>
  = note: required by `<ndarray::zip::Zip<(P,), D>>::from`
  = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

This occurs because IntoNdProducer is implemented for &mut ArrayBase but not for &mut &mut ArrayBase, and thus the following works

fn zip_ref_ref<Sa, Sb, D: Dimension>(mut a: &mut ArrayBase<Sa, D>, b: &ArrayBase<Sb, D>)
where Sa: DataMut<Elem = f64>,
      Sb: Data<Elem = f64>
{
    azip!(mut a (&mut *a), b (&*b) in { *a = 2.0*b });  // deref by hand !
}

But it is not intuitive.

Solution

Implement IntoNdProducer for &&ArrayBase and &mut &mut ArrayBase.

  • We do not have to implement it for &&&ArrayBase because we usually do not use &&ArrayBase as a function argument.
  • I cannot find a way using AsRef<ArrayBase> or other way. IntoNdProducer is already defined for various types, and generic implementation break them.

@jturner314
Copy link
Member

Thanks for reporting this. azip! has been a common source of confusion for a while now, and it would be good to make it easier to use and understand.

I'd prefer to avoid implementing IntoNdProducer for &mut &mut ArrayBase just to make azip cleaner. I'd prefer to change azip! instead, because it's been a common source of confusion for a while now.

Will you please let me know what you think about #626 instead of this PR?

For what it's worth, with the existing azip, you can write

azip!(mut a (a), b (b) in { *a = 2.0*b });

instead of

azip!(mut a (&mut *a), b (&*b) in { *a = 2.0*b });  // deref by hand !

@termoshtt
Copy link
Member Author

#626 seems much better :)

I'd prefer to avoid implementing IntoNdProducer for &mut &mut ArrayBase just to make azip cleaner.

I agree. This PR is hacky...

@bluss
Copy link
Member

bluss commented Sep 8, 2019

Thanks, yeah this has been declined and will be fixed another way.

@bluss bluss closed this Sep 8, 2019
@termoshtt termoshtt deleted the azip_ref_ref branch September 14, 2019 06:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants