Rust: tracking issue for `infer_static_outlives_requirements` (RFC 2093 spinoff)

Created on 13 Sep 2018  Â·  8Comments  Â·  Source: rust-lang/rust

As part of the work on RFC 2093 (rust-lang/rust#44493), we encountered a specific sub-question that we decided to spin out into its own feature gate called infer_static_outlives_requirements (#52761). The question is whether to infer T: 'static requirements from structs.

For example, does this struct require T: 'static?

struct Foo<T> {
  x: &'static T
}

There is no real implementation work to be done here, this is simply a policy question.

B-unstable C-tracking-issue T-lang

Most helpful comment

I don't know what we should do necessarily, but two reasons not to infer 'static right now:

  • For lifetimes other than 'static, there is some indication in the public signature that the type parameters are bound by those lifetimes, because they are also parameters. That is, given Iter<'a, T>, its almost always the case that there's a &'a T somewhere in the struct, and users expect that. But there's no visual distinction between a Foo<T> above and, for example, Vec<T>, indicating that T: 'static is implied.
  • Having decided to stabilize this for everything else, we'll be able to get more feedback on whether or not this is expected. That is, now that you never need to write T: 'a, we'll see if we get more user confusion about T: 'static suggesting that we should make this change.

All 8 comments

Are there particular strong reasons to treat 'static any different than other lifetimes here?
Otherwise, for reasons of uniformity/consistency, I'm strongly inclined that T: 'static should be inferred.

I'm not sure what you mean by "strong" — the inference itself has no problem with 'static. I think the motivation is that it is somehow surprising, but it's tricky to put my finger on why.

@nikomatsakis by strong I mean "very compelling" rather than "a bit compelling" :)

I don't know what we should do necessarily, but two reasons not to infer 'static right now:

  • For lifetimes other than 'static, there is some indication in the public signature that the type parameters are bound by those lifetimes, because they are also parameters. That is, given Iter<'a, T>, its almost always the case that there's a &'a T somewhere in the struct, and users expect that. But there's no visual distinction between a Foo<T> above and, for example, Vec<T>, indicating that T: 'static is implied.
  • Having decided to stabilize this for everything else, we'll be able to get more feedback on whether or not this is expected. That is, now that you never need to write T: 'a, we'll see if we get more user confusion about T: 'static suggesting that we should make this change.

Hmm, there's some precedent that Box<T> differs from Box<T + 'a> here, right?

But I agree that waiting for additional feedback here is the right plan.

I did some looking around and thus far it doesn't seem like anyone has used #![feature(infer_static_outlives_requirements)] and I don't expect the feature gate will ever see much usage because taking a dependency on nightly just for this seems unlikely when it's relatively easy to write T: 'static. Thus, the additional feedback we want may sadly never develop.

That said, I'm coming around to the idea that T: 'static should be inferred to keep the ruleset of the language smaller and thus make Rust easier to learn.

With respect to @withoutboats's first point, while I initially found it compelling, I've thought some more about it... Given that for a type Foo<'a, T> it's not given that T: 'a, since you may have struct Foo<'a, T>(&'a ConcreteType, T);, I think that there is really no fundamental difference for T: 'static. This becomes even clearer if we consider Foo<'a, T, U>; with such a type, I don't think the user should have expectations that T: 'a and U: 'a both hold; having that bound of one type parameter is not so uncommon imo.

I feel that not having the feature might be good for onboarding, as otherwise people who try to put references into types will get implicitly guided towards &'static, which is probably not what they actually wanted. This reminds me of elision, which also won't default to &'static for something like fn foo() -> &i32.

This issue hasn't been around for all that long; I think we should wait more time to see if anyone whos up saying it would be particularly helpful to them.

We discussed this in the lang team meeting and the general consensus was that, while we generally prefer to avoid special-cases in the language, 'static feels "different" than other lifetimes, and allowing inference for this particular bound could cause confusion.

Rather than FCP close'ing, we decided to leave this open and wait to see if users are confused by this special case. One thing that was pointed out was that users might not find this issue because the current error doesn't suggest using a feature gate nor point users towards this tracking issue-- this should be fixed.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dnsl48 picture dnsl48  Â·  3Comments

tikue picture tikue  Â·  3Comments

mcarton picture mcarton  Â·  3Comments

Robbepop picture Robbepop  Â·  3Comments

dtolnay picture dtolnay  Â·  3Comments