rust-lang / rust-lang/rust

Patterns sometimes ignores lifetimes.

Open
#144,312 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-borrow-checker A-lifetimes A-patterns C-bug I-ICE I-unsound P-high T-types
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Edit: This can cause UB. See https://github.com/rust-lang/rust/issues/144312#issuecomment-4750166207

I tried this code:

#[derive(PartialEq)]
struct Foo<'a>(&'a ());

#[allow(dead_code)]
struct Dummy<'a>(&'a ());
impl<'a> Dummy<'a> {
    const X: Foo<'a> = Foo(&());
}

fn identity<T>(x: T) -> T { x }

pub fn weird<'a>(_: &'a ()) {
    let Dummy::<'static>::X = { Dummy::<'a>::X };
    let Dummy::<'a>::X = { Dummy::<'static>::X };
    let Dummy::<'static>::X = Dummy::<'a>::X;
    let Dummy::<'a>::X = Dummy::<'static>::X;
    let Dummy::<'static>::X = { Foo(&()) as Foo<'a> };
    let Dummy::<'a>::X = { Foo(&()) as Foo<'static> };
    let Dummy::<'static>::X = identity(Foo(&()) as Foo<'a>);
    let Dummy::<'a>::X = identity(Foo(&()) as Foo<'static>);
    let Dummy::<'static>::X = Foo(&()) as Foo<'a>;
    // For some reason, the line below doesn't compile.
    let Dummy::<'a>::X = Foo(&()) as Foo<'static>;
}

I expected all of the let statements to cause compile errors, (or half of them, due to subtyping). Instead, all of the statements compile fine, except for the last one, which produced this compile error:

error: lifetime may not live long enough
  --> src/lib.rs:23:38
   |
12 | pub fn weird<'a>(_: &'a ()) {
   |              -- lifetime `'a` defined here
...
23 |     let Dummy::<'a>::X = Foo(&()) as Foo<'static>;
   |                                      ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`

I discovered this issue after some experimentation after @purplesyringa sent me this odd comment in the compiler: https://github.com/rust-lang/rust/blob/c0b282f0ccdab7523cdb8dfa41b23bed5573da76/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs#L506-L511

Meta

Reproducible on the playground with version 1.90.0-nightly (2025-07-21 9748d87dc70a9a6725c5)

@rustbot labels +A-patterns +A-borrow-checker +A-lifetimes

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 with the Rust 1.90.0-nightly version described in the issue, then read compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs around lines 506-511. Trace why constant patterns accept the shown lifetime combinations inconsistently. Done means the reproducer follows the intended lifetime rules and has regression coverage for the behavior.

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.