rust-lang / rust-lang/rust

Auto traits in opaque types impose bounds on wrong lifetime

Open
#158,777 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-auto-traits A-borrow-checker A-impl-trait A-inference A-variance C-bug T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

This code is minimized from code discovered by @danielhenrymantilla.

I tried this code:

struct X<'a>(&'a ());

unsafe impl Send for X<'static> {} // non-`Send` otherwise.

fn require_send(_: impl Send) {}

fn foo1<'a>(_: &'a i32) -> impl use<'a> + Sized {
    X::<'static>(&())
}

fn foo2<'a>(_: &'a i32) -> impl use<'a> + Send {
    X::<'static>(&())
}

fn main() {
    let x = 1;
    require_send(foo1(&x));
    let y = 2;
    require_send(foo2(&y));
}
error[E0597]: `x` does not live long enough
  --> src/main.rs:17:23
   |
16 |     let x = 1;
   |         - binding `x` declared here
17 |     require_send(foo1(&x));
   |     ------------------^^--
   |     |                 |
   |     |                 borrowed value does not live long enough
   |     argument requires that `x` is borrowed for `'static`
...
20 | }
   | - `x` dropped here while still borrowed
   |
note: requirement that the value outlives `'static` introduced here
  --> src/main.rs:5:25
   |
 5 | fn require_send(_: impl Send) {}
   |                         ^^^^

For more information about this error, try `rustc --explain E0597`.

I expected both the call to foo1 and foo2 to both compile. Instead, for some reason, only the call to foo1 caused a compile error. This seems incorrect, since auto traits ought to be seen through RPIT.

For some reason, in foo1, instead of the compiler imposing a requirement that the lifetime in X must be 'static, the compiler is instead imposing a requirement that 'a must be 'static.

Neither next-solver nor polonius fixes this.

cc @lcnr

Meta

Reproducible on the playground with version 1.98.0-nightly (2026-07-02 c397dae808f70caebab1)

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 minimized example on the Rust 1.98.0-nightly playground version cited in the issue. Trace how RPIT auto-trait bounds and lifetimes are handled for foo1 and foo2; done means the compiler no longer requires the argument lifetime to be 'static and both calls compile as expected.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.