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

op_ref false positive with deref coercions when comparing #2597

Open
euclio opened this issue Mar 31, 2018 · 11 comments
Open

op_ref false positive with deref coercions when comparing #2597

euclio opened this issue Mar 31, 2018 · 11 comments
Labels
C-bug Category: Clippy is not doing the correct thing E-medium Call for participation: Medium difficulty level problem and requires some initial experience. good-first-issue These issues are a good way to get started with Clippy I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied L-suggestion Lint: Improving, adding or fixing lint suggestions L-tests Lint: Lints test code

Comments

@euclio
Copy link
Contributor

euclio commented Mar 31, 2018

Perhaps related to #2042, but it seemed different enough to open a new issue.

With the following code: https://play.rust-lang.org/?gist=35d367db95cd56394d0bb9a05247b94c&version=nightly

fn main() {
    let a: &str = "abc";
    let b: String = "abc".to_owned();
    println!("{}", a > &b);
}

Clippy complains that the reference should be removed, but removing the reference causes the code to stop compiling.

@oli-obk
Copy link
Contributor

oli-obk commented Mar 31, 2018

Clippy on playpen is down. If memory serves right, isn't it also suggesting to deref the other side?

@euclio
Copy link
Contributor Author

euclio commented Apr 2, 2018

The error message reported by clippy is:

┌ euclio@apollo ~/repos/op_ref_test (git:master)
└╌╌┄┄ ❯❯ cargo +nightly clippy
   Compiling op_ref_test v0.1.0 (file:///Users/anrussell/repos/op_ref_test)
warning: taken reference of right operand
 --> src/main.rs:6:20
  |
6 |     println!("{}", a > &b);
  |                    ^^^^--
  |                        |
  |                        help: use the right value directly: `b`
  |
  = note: #[warn(op_ref)] on by default
  = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.191/index.html#op_ref

    Finished dev [unoptimized + debuginfo] target(s) in 1.37 secs

@oli-obk oli-obk added the C-bug Category: Clippy is not doing the correct thing label Apr 2, 2018
@oli-obk
Copy link
Contributor

oli-obk commented Apr 2, 2018

We need to suggest a deref on the lhs here, too.

@oli-obk oli-obk added the E-medium Call for participation: Medium difficulty level problem and requires some initial experience. label Apr 2, 2018
@ghost
Copy link

ghost commented Apr 18, 2018

From the playpen link, he is actually comparing &str and String. In this case, deref on the lhs doesn't work. I think this is a false positive since gt requires a reference.

fn main() {
    let a: &str = "abc";
    let b: String = "abc".to_owned();
    println!("{}", a > &b); // works
    println!("{}", *a > b); // doesn't work
}
   Compiling playground v0.0.1 (file:///playground)
error[E0308]: mismatched types
 --> src/main.rs:5:25
  |
5 |     println!("{}", *a > b); // doesn't work
  |                         ^ expected str, found struct `std::string::String`
  |
  = note: expected type `str`
             found type `std::string::String`

@oli-obk
Copy link
Contributor

oli-obk commented Apr 24, 2018

Dereferencing both sides works. We can probably figure this out by checking for autoref coercions

@ghost
Copy link

ghost commented Apr 24, 2018

I didn't know that was possible but what benefit does *a > *b have over a > &b?
Also this seems to be a regression of #1665.

@oli-obk
Copy link
Contributor

oli-obk commented Apr 25, 2018

The advantage is one less temporary variable (the comparison operator internally takes a reference to its arguments).

aopicier added a commit to aopicier/cryptopals-rust that referenced this issue Sep 16, 2018
@jsgf
Copy link
Contributor

jsgf commented Aug 7, 2019

I just ran into this with https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=890234c7ce6d7ccde1d036ae41d782d4

pub fn false_clippy_op_ref<T: Ord + PartialOrd>(array: &[T], val: &T, idx: usize) -> bool {
    &array[idx] < val
}

@flip1995 flip1995 added the I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied label Aug 8, 2019
@phansch phansch added the L-suggestion Lint: Improving, adding or fixing lint suggestions label Aug 24, 2019
@Manishearth Manishearth changed the title op_ref false positive when comparing op_ref false positive with deref coercions when comparing Sep 20, 2019
@Luro02
Copy link

Luro02 commented Nov 24, 2019

I think I ran into this too
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=d57a5e67a0a9e7d50e4bf85a76c7602a

pub fn example_problematic_lint(value: &String, rhs: &str) -> bool {
    &**value < rhs
}


fn main() {
    dbg!(example_problematic_lint(&"Hello".to_string(), "Worl"));
}

Clippy output

   Checking playground v0.0.1 (/playground)
warning: needlessly taken reference of left operand
 --> src/main.rs:3:5
  |
3 |     &**value < rhs
  |     --------^^^^^^
  |     |
  |     help: use the left value directly: `**value`
  |
  = note: `#[warn(clippy::op_ref)]` on by default
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#op_ref

    Finished dev [unoptimized + debuginfo] target(s) in 0.57s

flip1995 added a commit to flip1995/rust-clippy that referenced this issue Dec 3, 2019
@flip1995 flip1995 mentioned this issue Dec 3, 2019
flip1995 added a commit to flip1995/rust-clippy that referenced this issue Dec 3, 2019
@flip1995 flip1995 added L-tests Lint: Lints test code good-first-issue These issues are a good way to get started with Clippy labels Dec 3, 2019
@flip1995
Copy link
Member

flip1995 commented Dec 3, 2019

This is probably fixed by #4878, but needs more tests, e.g. #2597 (comment).

An improvement of this lint would still be to suggest a deref on both sides, when possible.

bors added a commit that referenced this issue Dec 3, 2019
Rustup

Included rustups:

- rust-lang/rust#66935 (syntax: Unify macro and attribute arguments in AST)
- rust-lang/rust#66941 (Remove `ord` lang item)

Fixes? #2597

changelog: none
@ssokolow
Copy link

ssokolow commented Aug 6, 2022

I just ran into this with a newtype I defined:

warning: taken reference of right operand
   --> src/lib.rs:208:37
    |
208 |         || f64::from(stats.words) < f64::from(stats.urls) * &*config.min_words_per_url
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^--------------------------
    |                                                             |
    |                                                             help: use the right value directly: `*config.min_words_per_url`
    |
    = note: `#[warn(clippy::op_ref)]` implied by `#[warn(clippy::all)]`
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#op_ref
error[E0277]: cannot multiply `f64` by `config::newtypes::PositiveF64`
   --> src/lib.rs:208:59
    |
208 |         || f64::from(stats.words) < f64::from(stats.urls) * config.min_words_per_url
    |                                                           ^ no implementation for `f64 * config::newtypes::PositiveF64`
    |
    = help: the trait `std::ops::Mul<config::newtypes::PositiveF64>` is not implemented for `f64`
    = help: the following other types implement trait `std::ops::Mul<Rhs>`:
              <&'a f32 as std::ops::Mul<f32>>
              <&'a f64 as std::ops::Mul<f64>>
              <&'a i128 as std::ops::Mul<i128>>
              <&'a i16 as std::ops::Mul<i16>>
              <&'a i32 as std::ops::Mul<i32>>
              <&'a i64 as std::ops::Mul<i64>>
              <&'a i8 as std::ops::Mul<i8>>
              <&'a isize as std::ops::Mul<isize>>
            and 49 others

Granted, I'll implement Mul after posting this, but I'm sure there are situations where that's not an option.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Clippy is not doing the correct thing E-medium Call for participation: Medium difficulty level problem and requires some initial experience. good-first-issue These issues are a good way to get started with Clippy I-suggestion-causes-error Issue: The suggestions provided by this Lint cause an ICE/error when applied L-suggestion Lint: Improving, adding or fixing lint suggestions L-tests Lint: Lints test code
Projects
None yet
Development

No branches or pull requests

7 participants