-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
new RFC: static_lifetime_in_statics #1623
Conversation
Seems like a reasonable idea; I've thought about proposing a change like this from time to time. There are in fact no other lifetime names in scope at all, so The RFC is a bit incomplete in that it doesn't seem to spell out how this should interact. Functions I think work today, so presumably they continue the same: static foo: fn(&u32) -> &u32 = ...; // for<'a> fn(&'a u32) -> &'a u32
static foo: &Fn(&u32) -> &u32 = ...; // &'static for<'a> Fn(&'a u32) -> &'a u32 For object types using trait SomeObject<'a> { ... }
static foo: &SomeObject = ...; // &'static SomeObject<'static>
static foo: &for<'a> SomeObject<'a> = ...; // &'static for<'a> SomeObject<'a> |
Exactly. I will extend the Detailed Design section to include your examples. |
|
||
Currently, having references in `static` and `const` declarations is cumbersome | ||
due to having to explicitly write `&'static ..`. On the other hand anything but | ||
static is likely either useless, unsound or both. Also the long lifetime name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I wrote, since 'static
is the only name in scope, it's certainly not "unsound" -- other names are just a guaranteed compilation error. I'd just drop this sentence.
Thank you @nikomatsakis for those detailed comments! |
I know this might be a little controversial, but I am for allowing full type inference in statics and consts, since it adds a nice symmetry, and makes a lot of things more ergonomic. |
@ticki As I wrote in the Alternatives section, even with full type inference, having the default still allows us to declare the types thus documenting them without writing out all those |
Sure, I was merely noting. I do support this RFC. |
Full inference would be great. I do however wonder two things: First, will this change give us a good etnough solution for the majority of cases (with its vastly smaller complexity)? And second, would I want to do the inference for complex statics in my head (because I cannot simply read the type if it's inferred, though IDEs could probably help with that)? Currently I think that on balance for simple cases writing the type is relatively cheap in terms of code size, whereas with more involved types (especially with types containing closures), I'd rather see them written down as documentation. But I may be wrong. |
It would certainly be convenient for us to do inference, but I am wary: it However, as the RFC argues, even if we did type inference, I imagine some On Fri, May 20, 2016 at 2:37 PM, llogiq [email protected] wrote:
|
I think symmetry with function signatures and other items (public API is explicitly typed) is more important than symmetry with What I sometimes wish for is inference of the length for array types, i.e. being able to write |
@nikomatsakis, I certainly agree that there are priorities, and it will likely increase complexity (although I can think of multiple ways to attack this). The change described in this RFC is relatively simple. @birkenfeld, I disagree. |
@ticki One difference between |
Yes, but the fundamental concept is the same: they're both value declarations associated with a particular identifier. |
I don't dispute that. But there isn't only one "class" in which these things can be placed - and I happen to think that consistency within another class - item-level signatures - is more important. |
There are a bunch of "fundamental concepts" lying around here - global vs local, interface vs implementation detail. Not all of them make local variables and constants/statics look similar. |
@ticki I agree that the fundamental concept is the same. I just argue that this is beside the point, because unlike
and now let's say someone changes |
If we ever got contravariance back, type Foo<'a> = fn(&'a Bar);
static BAZ: Foo = ...;
// BAZ: Foo<'static> might be a bit weird. Otherwise I like this. |
I'm not sure if we can differentiate between function argument and reference lifetimes. If we could, defaulting only the latter while leaving the former generic would be the best solution. |
The same issue already exists for lifetime elision so there's plenty of precedent. |
Another thing that could allow non- trait Foo<T> { const X: T; }
impl<'a> Foo<&'a u8> for &'a i32 {
const X: &'a u8 = &0;
} This doesn't seem particularly problematic on the face of it (especially given associated constants are unstable), but I haven't devoted much thought to it. |
@Ericson2314 @glaebhoerl @huonw I think that's the exact spot where we can strengthen the RFC: By defining the interaction between the struct SomeInnerType<'a> {
foo: &'a [u32]
}
struct SomeType<'a, 'b, 'c: 'a> {
x: &'a SomeInnerTyp<'c>,
y: Fn<'b>(&'b Foo) -> &'b Bar
} we could make a Note that this would make a difference based on the internals of Am I right or did I miss some corner case? (Edit: Fixed the wrong type) |
You can't have |
@notriddle: If I understand the RFC correctly, it explicitly talks about your example (emphasis mine):
|
I meant to reply to @llogiq. Sorry about the confusion. |
@notriddle The confusion is obviously mine. Thanks for helping to clear it up. |
Now I extended the Design section to hopefully clear up the confusion by describing interaction with a few other features. |
@nikomatsakis true. I guess my concern is we'd be providing sugar for something the user probably doesn't intend in that situation, but maybe it's better to be simple and consistent. We could instead just add a lint for inferred |
That sounds nice. As a beginner I just stumbled over this a little bit. |
Hear ye, hear ye! This RFC is now entering final comment period. The @rust-lang/lang team is currently inclined to accept the RFC. The conversation focused on a few points of clarification (e.g., what happens to anonymous bound regions in a fn type signature). It was also pointed out that while |
+1 |
Huzzah! The @rust-lang/lang team has decided to accept this RFC. |
pub trait Endpoint {
const ENDPOINT: &'static str;
// ...
}
impl Endpoint for UserList {
const ENDPOINT: &str = "user/list";
// ...
}
impl Endpoint for UserEdit {
const ENDPOINT: &str = "user/edit";
// ...
}
|
Adding
'static
lifetimes to every reference or generics lifetime value instatic
orconst
declarations adds no value. So this PR suggests we allow to omit them.Rendered