Skip to content

dyn Trait<'a> shouldn't carry 'a lifetime #104684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
yshui opened this issue Nov 21, 2022 · 5 comments
Open

dyn Trait<'a> shouldn't carry 'a lifetime #104684

yshui opened this issue Nov 21, 2022 · 5 comments
Labels
A-dyn-trait Area: trait objects, vtable layout A-lifetimes Area: Lifetimes / regions C-discussion Category: Discussion or questions that doesn't represent real issues. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@yshui
Copy link
Contributor

yshui commented Nov 21, 2022

I tried this code:

fn check<'a, T: Trait<'a> + ?Sized>() {}
trait Trait<'a>: 'static {}

fn check2<'a>() {
    check::<dyn Trait<'a> + 'static>();
}

I expected to see this happen: It compiles

dyn Trait<'a> should have an lifetime independent from 'a. i.e. dyn Trait<'a> + 'b should have lifetime 'b. in this particular case, 'b is 'static.

Instead, this happened:

error: lifetime may not live long enough
 --> src/lib.rs:5:5
  |
4 | fn check2<'a>() {
  |           -- lifetime `'a` defined here
5 |     check::<dyn Trait<'a> + 'static>();
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`

Related

#88904. Since this is another way of creating dyn Trait: !Trait, except in this case, I think the unsized coercion should be allowed, and dyn Trait does impl Trait.

@yshui yshui added the C-bug Category: This is a bug. label Nov 21, 2022
@yshui
Copy link
Contributor Author

yshui commented Nov 21, 2022

Besides giving dyn Trait<'a> a lifetime independent of 'a, I think if trait Trait<'a>: 'static, then dyn Trait<'a> should implicitly be : 'static

@Jules-Bertholet
Copy link
Contributor

It's an invariant of the type system that projections from a type can't have a lesser lifetime than that type. In other words, if T: 'static, then T::Some::Arbitary::Path: 'static must also hold (unless the path involves some non-'static lifetime parameter). If dyn Trait<'a> was 'static, this rule could be violated:

trait Foo {
    type Assoc;
}

impl<'a> Foo for dyn Trait<'a> {
    type Assoc = &'a u32;
}

// `<dyn Trait<'a> as Foo>::Assoc` is not `'static`, so `dyn Trait<'a>` cannot be `'static` either

@rustbot label -C-bug C-discussion A-lifetimes A-trait-objects T-types

@rustbot rustbot added A-lifetimes Area: Lifetimes / regions A-dyn-trait Area: trait objects, vtable layout C-discussion Category: Discussion or questions that doesn't represent real issues. T-types Relevant to the types team, which will review and decide on the PR/issue. and removed C-bug Category: This is a bug. labels Dec 16, 2023
@yshui
Copy link
Contributor Author

yshui commented Dec 16, 2023

@Jules-Bertholet hmm, ok.

What if we explicitly apply this rule and disallow the impl in this case?

impl<'a> Foo for dyn Trait<'a> + 'static {
    type Assoc = &'a u32; // error: <dyn Trait<'a> + 'static as Foo>::Assoc must outlive 'static
}

I would expect this at least needs an RFC, but does this make sense?

@Jules-Bertholet
Copy link
Contributor

Jules-Bertholet commented Dec 16, 2023

@yshui That would be a breaking change, as the impl for dyn Trait<'a> is currently accepted on stable Rust.

@yshui
Copy link
Contributor Author

yshui commented Dec 16, 2023

true, but that only affects impls explicitly for dyn Trait<'a> + 'lifetime, currently this + 'lifetime does nothing, so I doubt there's a lot of code out there written like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-dyn-trait Area: trait objects, vtable layout A-lifetimes Area: Lifetimes / regions C-discussion Category: Discussion or questions that doesn't represent real issues. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants