Skip to content
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

Interaction between elision and trait objects is not ideal #1302

Open
nikomatsakis opened this issue Oct 1, 2015 · 2 comments
Open

Interaction between elision and trait objects is not ideal #1302

nikomatsakis opened this issue Oct 1, 2015 · 2 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@nikomatsakis
Copy link
Contributor

As observed on rust-lang/rust#27248, the interaction between elision and trait objects changed recently as the result of a bug fix, but in some cases the older, buggy behavior may have been preferable. In particular, trait object defaults operate by different rules per RFC 599. I have also argued that object lifetime defaults ought to be treated differently from other lifetimes for the purpose of '_, which is closely tied to elision. However, it's unclear just what the new rules ought to be.

@huonw huonw added the T-lang Relevant to the language team, which will review and decide on the RFC. label Oct 2, 2015
@nikomatsakis
Copy link
Contributor Author

Here are some notes from our discussion in the language subteam meeting.

There are basically four options:

  1. Keep things as they are.
  2. Ignore 'static for purposes of elision altogether.
  3. Ignore object lifetime bound if defaulted for purposes of elision.
  4. Ignore object lifetime bound if trait has a 'static bound.
  5. Ignore object lifetime bound (regardless of whether it is defaulted)

Here are some examples, and how they behave under each of those. Let's take these traits:

trait Trait { }
trait TraitStatic:'static {}
trait TraitA<'a>: 'a { }

And then let's look at various examples and see how the rules play out:


fn foo(x: Box<Trait>) -> &i8 OR
fn foo(x: Box<TraitStatic>) -> &i8

Today these are equivalent to fn foo(x: Box<Trait+'static>) -> &'static i8 and fn foo(x: Box<TraitStatic+'static>) -> &'static i8 respectively. The 'static arises in the input because of the object lifetime defaulting rules from RFC 599, and then in the output because of the existing elision rules.

Interestingly, the first case becomes an error (and hence a regression!) under rules 2, 3, and 5 above. This is because those rules would cause us to ignore the 'static and hence the output would be unconstrained. Rule 4 doesn't apply to the first case, but it does regress the second case. These regressions are pretty unfortunate, and suggest that we need to consider other options beyond the ones I listed. Nonetheless, let's carry on.


fn foo(x: Box<TraitA>) -> &i8

This case works the same under all proposals. It expands to fn foo<'a>(x: Box<TraitA<'a>+'a>) -> &'a i8. The input again comes from RFC 599. In this case though, no error occurs in the output because all of the proposals would consider the 'a appearing in TraitA<'a> to be a lifetime reference.


fn foo(x: &Trait) -> &i8

Similarly to the previous one, this case works the same under all proposals. It expands to:

fn foo<'a>(x: &'a (Trait+'a)) -> &'a i8

the reasons are basically the same.


fn foo(x: &TraitStatic)

This is an error today because the input has two lifetimes, 'a and 'static, but would expand to fn foo<'a>(x: &'a (TraitStatic+'static)) -> &'a i8 under any of the alternative proposals.


fn foo(x: &TraitA) -> &i8

This is an error today because you get two distinct lifetimes, the & and the parameter to TraitA. It continues to be an error under all the proposals.


fn foo<'a,'b>(x: &'a (Trait+'b)) -> &i8

Today this is an error. I would like it to continue being an error. The only rule where it is NOT an error is rule 5.


fn foo<'a,'b>(x: &'a (TraitStatic+'static)) -> &i8

Today this is an error. I would like it to continue being an error, but it will not be an error under rules 4 or 5.

@nikomatsakis
Copy link
Contributor Author

cc @rust-lang/lang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests

2 participants