rust-lang / rust-lang/rust-clippy

needless_borrowed_reference for lambdas not immediately typed

Open
#11,566 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

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

Description

Summary

needless_borrowed_reference triggers when a lambda is passed to construct a struct, where the type-restriction is only enforced for an implementation. When the type-restriction is eager (like directly to a function), it doesn't appear to trigger. The lint is a false positive because when applying the lint's suggestion, the compiler does not backward-infer that the closure should be a tuple-reference rather than a tuple. The lifetime is specific to the struct and return-type, which can't be (easily) expressed in lambda typing, thus adding : &(_,) wont work. There are workarounds to properly type the lambda, but are inappropriate fixes.

Lint Name

needless_borrowed_reference

Reproducer

I tried this code:

(playground)

#![deny(clippy::needless_borrowed_reference)]
#![allow(dead_code)]

struct Wrap<'a, L, R>(&'a (L,), R);

trait Callable {
    fn call(&self);
}

impl<
    'a,
    T,
    F: Fn(&'a (T,)) -> V,
    V,
> Callable for Wrap<'a, T, F> {
    fn call(&self) {}
}

fn test() {
    Wrap(&("blah",), |&(ref v,)| v).call();
}

I saw this happen:

    Checking playground v0.0.1 (/playground)
error: dereferencing a tuple pattern where every element takes a reference
  --> src/lib.rs:20:23
   |
20 |     Wrap(&("blah",), |&(ref v,)| v).call();
   |                       ^^^^^^^^^
   |
   = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
note: the lint level is defined here
  --> src/lib.rs:1:9
   |
1  | #![deny(clippy::needless_borrowed_reference)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: try removing the `&` and `ref` parts
   |
20 -     Wrap(&("blah",), |&(ref v,)| v).call();
20 +     Wrap(&("blah",), |(v,)| v).call();
   |

I expected to see this happen:

Version
0.1.74 (2023-09-24 37390d6)
Additional Labels

No response

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 supplied Rust reproducer and examining the needless_borrowed_reference lint entry point. Compare the lambda passed to Wrap with the eagerly typed function case described in the issue. Done means the lint no longer emits this false-positive suggestion while still detecting the intended pattern, with regression coverage for the reproducer.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 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.