Skip to content

member constraints are order-dependent #140569

Open
@lcnr

Description

@lcnr
struct Inv<'a>(*mut &'a ());
fn mk<'m>() -> (Inv<'m>, Inv<'m>) {
    loop {}
}
fn ok<'a, 'b: 'a>() -> (impl Sized + use<'a>, impl Sized + use<'b>) {
    mk()
}
fn err<'a, 'b: 'a>() -> (impl Sized + use<'b>, impl Sized + use<'a>) {
    mk()
}

this fails with

error[E0700]: hidden type for `impl Sized` captures lifetime that does not appear in bounds
 --> src/lib.rs:9:5
  |
8 | fn err<'a, 'b: 'a>() -> (impl Sized + use<'b>, impl Sized + use<'a>) {
  |            --                                  -------------------- opaque type defined here
  |            |
  |            hidden type `Inv<'b>` captures the lifetime `'b` as defined here
9 |     mk()
  |     ^^^^
  |
help: add `'b` to the `use<...>` bound to explicitly capture it
  |
8 | fn err<'a, 'b: 'a>() -> (impl Sized + use<'b>, impl Sized + use<'a, 'b>) {
  |                                                                   ++++

We've got 'm member ['a, 'static] and 'm member ['b, 'static]. The final region chosen for 'm depends on the order in which we apply these constraints:

  • 'm member ['b, 'static] chooses 'b
  • 'm member ['a, 'static] as 'a: 'b does not hold, this has to choose 'static
  • we end up with 'm = 'static which satisfies both member constraints

and alternatively:

  • 'm member ['a, 'static] chooses 'a
  • 'm member ['b, 'static] can still choose 'b as 'b: 'a holds
  • we end up with 'm = 'b which means that 'm member ['a, 'static] does not hold

Fixing this is not too difficult, we can "simply" apply member constraints for each member region until we reach a fixpoint. I will implement this separately once #139587 landed.

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)A-impl-traitArea: `impl Trait`. Universally / existentially quantified anonymous types with static dispatch.C-bugCategory: This is a bug.T-typesRelevant to the types 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