Skip to content

Suggest manually rebinding an argument when it would help with variance #144267

@meithecatte

Description

@meithecatte

Code

struct Thing;

fn consume(_v: Vec<&Thing>) {}

fn doit(mut v: Vec<&Thing>) {
    let x = Thing;
    v.push(&x);
    consume(v);
}

Current output

error[E0597]: `x` does not live long enough
 --> src/lib.rs:7:12
  |
5 | fn doit(mut v: Vec<&Thing>) {
  |                    - let's call the lifetime of this reference `'1`
6 |     let x = Thing;
  |         - binding `x` declared here
7 |     v.push(&x);
  |     -------^^-
  |     |      |
  |     |      borrowed value does not live long enough
  |     argument requires that `x` is borrowed for `'1`
8 |     consume(v);
9 | }
  | - `x` dropped here while still borrowed

Desired output

error[E0597]: `x` does not live long enough
 --> src/lib.rs:7:12
  |
5 | fn doit(mut v: Vec<&Thing>) {
  |                    - let's call the lifetime of this reference `'1`
6 |     let x = Thing;
  |         - binding `x` declared here
7 |     v.push(&x);
  |     -------^^-
  |     |      |
  |     |      borrowed value does not live long enough
  |     argument requires that `x` is borrowed for `'1`
8 |     consume(v);
9 | }
  | - `x` dropped here while still borrowed
help: consider creating a new binding to let lifetime `'1` contract
5 | fn doit(mut v: Vec<&Thing>) {
  |     let mut v = v;
        ++++++++++++++

Rationale and extra context

The example shows a simplified version of a gnarly lifetime error encountered in the wild, which could also be resolved by adding a seemingly useless rebinding of the function argument, like so:

pub struct Thing;

fn consume(_v: Vec<&Thing>) {}

pub fn doit(v: Vec<&Thing>) {
    let mut v = v;
    let x = Thing;
    v.push(&x);
    consume(v);
}

It might also be the case that instead of creating diagnostics for this case, we would like to introduce a language change to prevent this from being a thing in the first place (e.g. by automatically introducing such re-binds everywhere, or tweaking the borrow checker in some way). But that's a whole can of worms...

Other cases

Rust Version

[i tested on the playground, but the issue also occurs on my laptop, where i have the following version]
rustc 1.89.0-nightly (1bbd62e54 2025-05-29)
binary: rustc
commit-hash: 1bbd62e547ba5cc08ccb44c27def3d33195d2dd5
commit-date: 2025-05-29
host: x86_64-unknown-linux-gnu
release: 1.89.0-nightly
LLVM version: 20.1.5

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions