rust-lang / rust-lang/rust-clippy

useless_asref message not accurate for mut slices

Open
#5,862 5 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug I-suggestion-causes-error
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

Hi. (Thanks for clippy. I just discovered it and I found it really quite helpful - it found several bugs and a number of simplifications in the small project I have just run it on.)

Consider this code:

use std::io;
use std::io::{Read,Write};

struct Thing;

impl Read for Thing {
    fn read(&mut self, orig_buf: &mut [u8]) -> Result<usize,io::Error> {
        let orig_wanted = orig_buf.len();
        #[allow(clippy::useless_asref)]
        let mut buf = orig_buf.as_mut();
        // without the .as_mut():
        /*
11 |     fn read(&mut self, orig_buf: &mut [u8]) -> Result<usize,io::Error> {
   |                        -------- move occurs because `orig_buf` has type `&mut [u8]`, which does not implement the `Copy` trait
...
14 |         let mut buf = orig_buf;
   |                       -------- value moved here
...
21 |         dbg!(&orig_buf[0..generated]);
   |               ^^^^^^^^ value borrowed here after move
        */
        
        // imagine more complex write sequence
        buf.write_all(&[ 1, 2 ])?;

        let generated = orig_wanted - buf.len();
        dbg!(&orig_buf[0..generated]);
        Ok(generated)
    }
}

I fed it to clippy. Without the #[allow], clippy issues a warning for orig_buf.as_mut,

warning: this call to `as_mut` does nothing
  --> src/lib.rs:13:23
   |
13 |         let mut buf = orig_buf.as_mut();
   |                       ^^^^^^^^^^^^^^^^^ help: try this: `orig_buf`
   |

But that's not right. Effectively, .as_mut() is "cloning" the reference by reborrowing the underlying slice.

Possibly .as_mut() is poor style for this and this would be preferred style:

        let mut buf = &mut *orig_buf;

In which case suggesting this in those kind of cases would be better. I'm not sure this problem is limited to slices. It seems to exist (at least) for any mutable reference-like thing, where as_ref returns a newly mutable reference to the same underlying data.

Meta
  • cargo clippy -V: clippy 0.0.212 (6c8927b 2020-07-26)
  • rustc -Vv:
rustc 1.47.0-nightly (6c8927b0c 2020-07-26)
binary: rustc
commit-hash: 6c8927b0cf80ceee19386026cf9d7fd4fd9d486f
commit-date: 2020-07-26
host: x86_64-unknown-linux-gnu
release: 1.47.0-nightly
LLVM version: 10.0

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the example in src/lib.rs with the useless_asref lint enabled, then trace the lint's diagnostic for mutable references. Done means the lint no longer gives an inaccurate removal suggestion for this case, with regression coverage for the reported behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.