No method named `inv` found for struct `rug::Rational` in the current scope

Hi,
here is a code snippet utilizing the rug 1.19.2 crate:

use rug::Rational;
fn main() {
    let a = Rational::from((137,-42));
    let b = Rational::from((2,3));
    println!("{:?}*{:?} = {:?}", a, b, a.clone()*b.clone());
    println!("({:?})^(-1) = {:?}", a, a.clone().inv());
}

I create two Rational-structs. In the first println I multiply them, utilizing the Mul-tait, and in the second line I try to invert one of the Rationals, utilizing the Inv-trait. Both traits are implemented for the rational struct:
impl-Inv-for-Rational
impl-Mul-for-Rational
When trying to build the code I get the following error

error[E0599]: no method named `inv` found for struct `Rational` in the current scope
 --> src/main.rs:7:49
  |
7 |     println!("({:?})^(-1) = {:?}", a, a.clone().inv());
  |                                                 ^^^ method not found in `Rational`

For more information about this error, try `rustc --explain E0599`.
error: could not compile `testing` (bin "testing") due to previous error

For some reason I cannot use the inv on the Rational struct, although it should be implemented.
The error message is not helpful at all. I know that the method is not in scope, but how do I get it?
Can someone explain to me what I did wrong and how to fix it?

Thanks

  1. You need to include the num-traits feature in the rug dependency.
  2. You need to bring the Inv trait from the num-traits crate into scope, and for that...
  3. You need to add num-traits as a dependency.

So, in Cargo.toml:

rug = { version = "1.19.2", features = ["num-traits"] }
num-traits = "0.2.15"

...and in your program:

use num_traits::Inv;

(This is for Inv; similarly for Mul.)

1 Like

Alternatively rug::Rational provides a method recip that does the same thing as inv, but since it's defined on the struct itself it doesn't need other traits to be in scope.

Thank you. That solves it.
Why is it designed that way? I would have expected the rug crate to have num-traits as a dependency and automatically load all the features.

Short FYI: You can write let product = dbg!(a * b); (or dbg!(a, b, a * c)) instead of the complex println! here.

1 Like

As previously noted, the operation you want is implemented as recip by rug. Compatibility with num-traits is an optional extra.

In general, there is an expectation that crates don't just auto-enable everything by default, since turning features off is more difficult and inconvenient than turning them on. So crates will typically default to a conservative set of functionality, with useful but potentially unnecessary code disabled until explicitly enabled. For example: if you aren't already using the num-traits crate, or don't need to interoperate with code that uses it, then rug supporting num-traits probably isn't particularly useful.

It's also worth noting that rug does have num-traits as a dependency (specifically an optional dependency). Adding the dependency to your code is so that you have access to its traits.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.