rust-lang / rust-lang/rust-clippy

Inconsistent handling of to_string() removal suggestion between field and method access

Open
#13,726 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Summary

I have 2 values to pass to a function. The first is borrowed (indirectly) from a field in the second, and the function needs a mutable reference of the second. So I am making a copy (to_string()) of the first, to avoid the conflicting borrows. But clippy suggests removing to_string(), which would result in a compiler error.

However, this suggestion only happens if the field is borrowed via a method. If done directly with the field instead of an accessor method, clippy does not make the (invalid) suggestion.

Lint Name

unnecessary_to_owned

Reproducer

Here is a complete example:

struct Something {
    value: String,
    // other fields
}

impl Something {
    fn value(&self) -> &str {
        &self.value
    }
}

fn use_it(_value: &str, _thing: &mut Something) {
    // do stuff
}

fn main() {
    let mut thing = Something { value: "abc".to_string() };

    // This (using field `value` directly) is fine, does not generate a warning:
    use_it(&thing.value.to_string(), &mut thing);

    // But this (using method `value()` to read field `value`) generates a warning:
    use_it(&thing.value().to_string(), &mut thing);

    // Using the suggestion results in a compiler error because of the immutable and mutable borrows together:
    // use_it(thing.value(), &mut thing);
}

The first call to use_it (using the field directly) does NOT result in a warning. But the second call results in:

warning: unnecessary use of `to_string`
  --> src/main.rs:23:12
   |
23 |     use_it(&thing.value().to_string(), &mut thing);
   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `thing.value()`
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned
   = note: `#[warn(clippy::unnecessary_to_owned)]` on by default

And the third call to use_it with the suggested change (commented out) would result in a compiler error because of the conflicting borrows.

Version
rustc 1.81.0 (eeb90cda1 2024-09-04)
binary: rustc
commit-hash: eeb90cda1969383f56a2637cbd3037bdf598841c
commit-date: 2024-09-04
host: x86_64-apple-darwin
release: 1.81.0
LLVM version: 18.1.7
Additional Labels

@rustbot label +I-suggestion-causes-error

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 running the complete Rust reproducer and inspecting the unnecessary_to_owned lint, comparing the direct field access with the accessor-method case. Done means the lint no longer emits a suggestion that causes the shown conflicting-borrow compiler error, while preserving valid suggestions and adding or updating coverage for both forms.

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
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.