Skip to content

TAIT: allow using '_ to reference the current lifetime #138620

Open
@erickt

Description

@erickt

We were doing some experimentation with type alias impl trait to make a macro that can associate compile-time constants with inferred types, and I think we're running into either a bug or unimplemented feature. We're hoping to use this so we can take a println!(...) -ish format string and access associated constants at compile time for runtime values. Unfortunately it seems Rust wants us to provide the name of the current lifetime, but it doesn't accept '_. Here's a simplified version of what we're trying to do:

#![feature(type_alias_impl_trait)]

trait MyTrait {
    const ARG: &'static str;
}

impl MyTrait for &str {
    const ARG: &'static str = "%s";
}

fn main() {
    let string = String::new();

    type T<'a> = impl MyTrait;
    let _: T<'_> = string.as_str();
    const ARG: &str = T::ARG;

    println!("{:?}", ARG);
}

This results in this error:

   Compiling playground v0.0.1 (/playground)
error[E0792]: expected generic lifetime parameter, found `'_`
  --> src/main.rs:15:12
   |
14 |     type T<'a> = impl MyTrait;
   |            -- this generic parameter must be used with a generic lifetime parameter
15 |     let _: T<'_> = string.as_str();
   |            ^^^^^

error[E0597]: `string` does not live long enough
  --> src/main.rs:15:20
   |
12 |     let string = String::new();
   |         ------ binding `string` declared here
...
15 |     let _: T<'_> = string.as_str();
   |            -----   ^^^^^^ borrowed value does not live long enough
   |            |
   |            type annotation requires that `string` is borrowed for `'static`
...
19 | }
   | - `string` dropped here while still borrowed

However it does work if we can use a named lifetime:

#![feature(type_alias_impl_trait)]

trait MyTrait {
    const ARG: &'static str;
}

impl MyTrait for &str {
    const ARG: &'static str = "%s";
}

fn func<'b>(s: &'a str) {
    type T<'a> = impl MyTrait;
    let _: T<'b> = s;
    const ARG: &str = T::ARG;

    println!("{:?}", ARG);
}

fn main() {
    let string = String::new();
    func(string.as_str());
}

Meta

rustc --version --verbose:

1.87.0-nightly (2025-03-16 227690a258492c84ae99)

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-type_alias_impl_trait`#[feature(type_alias_impl_trait)]`T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions