-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Open
Labels
A-borrow-checkerArea: The borrow checkerArea: The borrow checkerA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsA-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityHigh priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.
Description
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:
rust/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
Lines 506 to 511 in c0b282f
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get | |
// ignored. However that should be pretty much impossible since consts that do not depend on | |
// generics can only mention the `'static` lifetime, and how would one have a type that's | |
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem | |
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck | |
// can ensure that the type really implements `PartialEq`. |
Meta
Reproducible on the playground with version 1.90.0-nightly (2025-07-21 9748d87dc70a9a6725c5)
@rustbot labels +A-patterns +A-borrow-checker +A-lifetimes
Metadata
Metadata
Assignees
Labels
A-borrow-checkerArea: The borrow checkerArea: The borrow checkerA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsA-patternsRelating to patterns and pattern matchingRelating to patterns and pattern matchingC-bugCategory: This is a bug.Category: This is a bug.I-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessP-highHigh priorityHigh priorityT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.