rust-lang / rust-lang/rfcs

Lifetime contravariance is not taken into account

Open
#2,112 6 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

T-lang
Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

Consider the following, sane and compliant Rust code:

// Pred<T> is contravariant in T
struct Pred<T>(Box<Fn(&T) -> bool>); // same as Box<for<'a> Fn(&'a T) -> bool

fn main() {
}

This works because functions are contravariant in their arguments. Here, Fn(&T) implies that T is used in a contravariant position, so the lifetime is elided thanks to HRTB.

Now consider:

use std::marker::PhantomData;

struct Foo<T> { // contravariant in T
    id: u64,
    _t: PhantomData<fn(T)> // contravariant in T
}

struct Bar<'a> { // opaque type but it’s like a reference to something
    a: &'a u32
}

struct Zoo {
    foo: Foo<Bar> // here, because Foo is contravariant, it shouldn’t care about Bar’s lifetime
    // it should be the same as the – non-existent – syntax:
    // foo: Foo<for<'a> Bar<'a>>
}

fn main() {
}

There’s a problem of missing lifetime in foo: Foo<Bar>. Here, the lifetime is needed, but I really don’t get why, since Foo doesn’t care, being contravariant in its type parameter.

We either need a way to express foo: Foo<for<'a> Bar<'a>> or its elided version foo: Foo<Bar>, because the lifetime is not required here.

Contributor guide

No contributing guide indexed for this repository

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 with the two Rust examples in the issue and read the linked HRTB documentation. Investigate how lifetime elision and variance interact for the proposed Foo<Bar> forms, then determine which syntax and semantics would be required. Done means an agreed language design that resolves the missing-lifetime case and can be specified for Rust.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.