Skip to content

Implied bounds don't work for traits on &Self #47670

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
jpetkau opened this issue Jan 22, 2018 · 4 comments
Closed

Implied bounds don't work for traits on &Self #47670

jpetkau opened this issue Jan 22, 2018 · 4 comments
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jpetkau
Copy link

jpetkau commented Jan 22, 2018

If a trait has a bound on &Self, it doesn't seem to work as an implied bound.

For example (also https://gist.github.com/671c7746b96c86f9eb0e39176325157a):

use std::ops::Add;

pub trait Numoid where
  Self: Sized,
  for<'a> &'a Self: Add<Self, Output = Self>
{}

impl<N> Numoid for N where
  for<'a> &'a N: Add<N, Output = N>
{}

pub fn compute<N: Numoid>(a: N, b: N) -> N
    // where for<'a> &'a N: Add<N, Output = N> // redundant bound is required
{ &a + b }

This produces:

error[E0277]: the trait bound `for<'a> &'a N: std::ops::Add<N>` is not satisfied
  --> src/main.rs:20:1
   |
20 | / pub fn compute<N>(a: N, b: N) -> N
21 | | where
22 | |     N: Numoid,
23 | |     // for<'a> &'a N: Add<N, Output = N>, // redundant bound is required
...  |
27 | |     b + d
28 | | }
   | |_^ no implementation for `&'a N + N`
   |
   = help: the trait `for<'a> std::ops::Add<N>` is not implemented for `&'a N`
   = help: consider adding a `where for<'a> &'a N: std::ops::Add<N>` bound
   = note: required by `Numoid`

It works if the 'where' on fn compute is uncommented. Other implicit bounds in the same trait also work (e.g. for<'a> Self: Add<&'a Self> is fine).

This comes up when trying to write generic numeric code. I want to be explicit about using moves/refs to avoid unnecessary clones of things like BigInt, which requires binary operators to have the full set of overloads (i.e. a+b, &a+b, a+&b, &a+&b). BigInt and other numeric types support all these, and they work as explicit bounds, but repeating them on every function gets unwieldy quickly.

@ExpHP
Copy link
Contributor

ExpHP commented Jan 23, 2018

I believe this should eventually be addressed by the accepted Implied bounds RFC (tracking issue), which prescribes that all where bounds on traits will become implied.

@jpetkau
Copy link
Author

jpetkau commented Jan 24, 2018

Ah, I thought that RFC was already implemented, and this was a bug. I guess it's just not done yet?

@ExpHP
Copy link
Contributor

ExpHP commented Jan 24, 2018

Not much was said about it during the impl period, at least not that I can find. I added a note about what appears to be the current progress to the tracking issue, though somebody in the know may have more to add.

@pietroalbini pietroalbini added C-enhancement Category: An issue proposing an enhancement or a PR with one. A-trait-system Area: Trait system T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 6, 2018
@jonas-schievink
Copy link
Contributor

Closing in favor of #44491 / #20671

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-trait-system Area: Trait system C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants