Skip to content
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

Writing float::pow(int) causes rustc to suggest using powf, not powi #101823

Open
ash2x3zb9cy opened this issue Sep 14, 2022 · 1 comment
Open
Labels
A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@ash2x3zb9cy
Copy link

While trying to raise a float to an integer power, if the user tries to write float.pow(int), rustc suggests using powf, which then results in a type error. rustc then suggests casting the int to a float with as. The correct fix would instead be to use powi.

Given the following code: [playground]

fn main() {
    let x: f32 = 10.0;
    let p: i32 = 3;
    let x_cubed = x.pow(p);
    println!("{} cubed is {}", x, x_cubed);
}

The current output is:

error[[E0599]](https://doc.rust-lang.org/stable/error-index.html#E0599): no method named `pow` found for type `f32` in the current scope
 --> src/main.rs:4:21
  |
4 |     let x_cubed = x.pow(p);
  |                     ^^^ help: there is an associated function with a similar name: `powf`

For more information about this error, try `rustc --explain E0599`.

When using the suggested fix, the output is:

error[[E0308]](https://doc.rust-lang.org/stable/error-index.html#E0308): mismatched types
 --> src/main.rs:4:26
  |
4 |     let x_cubed = x.powf(p);
  |                     ---- ^ expected `f32`, found `i32`
  |                     |
  |                     arguments to this function are incorrect
  |
note: associated function defined here
help: you can convert an `i32` to an `f32`, producing the floating point representation of the integer, rounded if necessary
  |
4 |     let x_cubed = x.powf(p as f32);
  |                            ++++++

For more information about this error, try `rustc --explain E0308`.

Ideally the output should look like:

error[[E0599]](https://doc.rust-lang.org/stable/error-index.html#E0599): no method named `pow` found for type `f32` in the current scope
 --> src/main.rs:4:21
  |
4 |     let x_cubed = x.pow(p);
  |                     ^^^ help: there is an associated function with a similar name: `powi`

For more information about this error, try `rustc --explain E0599`.

The ideal output provides a working fix, and is likely to be more correct to the user's intended function.

@ash2x3zb9cy ash2x3zb9cy added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Sep 14, 2022
@chenyukang
Copy link
Member

chenyukang commented Sep 15, 2022

Currently, the Levenshtein based suggestions do not checking the type matching of arguments for candidates,
and only will give one final suggestion.

  fn candidate_method_names(&self) -> Vec<Ident> {
        let mut set = FxHashSet::default();
        let mut names: Vec<_> = self
            .inherent_candidates
            .iter()
            .chain(&self.extension_candidates)
            .filter(|candidate| {
                if let Some(return_ty) = self.return_type {
                    self.matches_return_type(&candidate.item, None, return_ty)
                } else {
                    true
                }
            })
            .map(|candidate| candidate.item.ident(self.tcx))
            .filter(|&name| set.insert(name))
            .collect();

        // Sort them by the name so we have a stable result.
        names.sort_by(|a, b| a.as_str().partial_cmp(b.as_str()).unwrap());
        names
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints 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

2 participants