Hacker News new | past | comments | ask | show | jobs | submit login

Sorry, I probably edited my comment while you were replying and added a couple links.

Check misconception 2 here, I think it addresses your point.

https://github.com/pretzelhammer/rust-blog/blob/master/posts...

EDIT to your edit:

> 'static in this context would mean that all instances of T must be 'static.

You mean in T: 'static?

No. It means that any instance passed as type T must be bound by 'static and therefore could be held up to the end of 'static. This does not mean that they're allocated at compile time, it just so happens that static variables (allocated at compile time) are 'static but the causality is reversed.

> If you want something to mean "A type cannot have references in it" then invent a 'noref lifetime.

It can have references in it! As long as they're bound by 'static.

Here's an example: https://play.rust-lang.org/?version=stable&mode=debug&editio...




Oh, I've read that.

I just maintain that the word 'static is being overloaded here to mean multiple different things.

'static is not the "lifetime of the entire application" when it is used in the context of T: 'static.

> It can have references in it! As long as they're bound by 'static.

:)

...but it can also have values in it which are not 'static.

So is T: 'static, or not?

It's arbitrary semantics; ...but my take on it is:

- IF you take "x is 'static" as meaning the "X is valid for entire lifetime of the application"

then if:

- x: &'static 'is static' and must be valid for the entire lifetime of the application.

I would expect:

- x: T + 'static 'is static' and must be valid for the entire lifetime of the application.

I'm happy to agree that's not what it does mean, what I'm saying is that it is inconsistent for it not to mean that.


> 'static is not the "lifetime of the entire application" when it is used in the context of T: 'static.

Yes it is.

T: 'static means T can live up to the end of the "lifetime of the entire application".

> ...but it can also have values in it which are not 'static.

I don't follow. Values are indeed bound by 'static. If they weren't we wouldn't be able to pass values to other threads (which can potentially last as long as our application's main thread).

> 'static is not the "lifetime of the entire application" when it is used in the context of T: 'static.

It is. Any owned instance without non-'static references inside can live up to the "lifetime of the entire application". You might drop them earlier if you wanted to, but you don't have to since it can live up to the "lifetime of the entire application" and therefore can be passed for example into a thread that can hold the value up to the end of the "lifetime of the entire application".

Any owned value can be held indefinitely as long as the program is running.

I'm taking a guess here: you mean that values' lifetimes can be constrained (I guess you mean by dropping the actual value). But it's the owner the one that ended it earlier, not the caller (where 'static applied). You will never be able to have an owned value with a lifetime shorter than 'static without dropping it and, if you drop it, you cannot pass it anywhere. Hence why any owned type that is passed is, by definition, bound by 'static.

> ...but my take on it is:

> - IF you take "x is 'static" as meaning the "X is valid for entire lifetime of the application"

> then if:

> - x: &'static 'is static' and must be valid for the entire lifetime of the application.

> I would expect:

> - x: T + 'static 'is static' and must be valid for the entire lifetime of the application.

Your expectations are correct and that's what it is. Just replace "must be valid" with "can live up to".

That's why you need to pass T: 'static to threads, because a separate thread needs something to hold up to the end of the application since a thread can potentially never end.

https://doc.rust-lang.org/std/thread/fn.spawn.html


Fair I guess; we're just arguing semantics. The point I was originally making is that:

'a: 'static is read "'a outlives 'static" [1]

T: 'static is read "T is bounded by 'static" (apparently, although I can't find a reference to it).

The syntax is the same, the meaning is different.

Maybe the 'static part of these two things is the same, but they seem to me to:

- mean different things

- use the same syntax

It is what it is I guess... just confusing as to why it was decided to use the same syntax for these things, instead of something different.

You could argue that adding new syntax makes the language more complicated; but I'm not sure. Does it make it less complicated when you overload the same syntax with multiple different contextual meanings?

Opinions probably vary.

[1] - https://doc.rust-lang.org/reference/trait-bounds.html#lifeti...


What confuses me is... why do you think the meaning is different? There is no meaning overload. It's a single meaning.

T: 'static would happily typecheck with &'a str if 'a: 'static.

T: 'static typechecks:

- OwnedValue

- OwnedValueWithReferences<'a> where 'a: 'static

- &'a ReferencedValue where 'a: 'static /// &'static ReferencedValue

- Foo<&'a Bar> where 'a: 'static /// Foo<&'static Bar>

...and more.

See the example here: https://play.rust-lang.org/?version=stable&mode=debug&editio...

Notice how bar2 has a &'a str where 'a: 'static and it can be happily passed to bar.

Of course in T: 'static you're subtyping a type and in 'a: 'static you're subtyping a lifetime (which implicitly subtypes the type that it's applied on)... but the ": 'static" part means exactly the same: "the left part of this bound can live up to the end of the application". Whether it's a lifetime, a borrowed type or an owned type does not matter.

> It is what it is I guess... just confusing as to why it was decided to use the same syntax for these things, instead of something different.

Because they are the same.

We could of course separate them into 'noref, 'yesrefbutstatic, 'staticref, etc. But then we'd have a needlessly restrictive std:.thread::spawn that would accept only Owned, or only Owned<'static> or only &'static Referenced. The implications are the same, hence they're the same. We wouldn't gain anything and we'd be needlessly restricted.

A simpler way to put it: owned values have an implicit 'static lifetime.


What you say makes sense... but I struggle to reconcile it with reality.

If "the left part of this bound can live up to the end of the application" then why is &a not 'a where 'a: 'static? a can live up to the end of the application. &a can live up to the end of the application.

Why is the result "argument requires that `a` is borrowed for `'static`"

    fn foo<'a: 'static>(a: &'a str) { println!("{}", a) }
    pub fn main() { 
      let a = "hello world".to_string();
      foo(&a);
    }
So I guess I'm going to have to just agree to disagree on this one and bow out of this conversation thread I'm afraid.

[1] -- https://play.rust-lang.org/?version=stable&mode=debug&editio...


What?

If you do 'a: 'static, then you just said 'a is at least as long as 'static.

When you borrow the String, you just created a lifetime that is not as long as 'static. Variables are dropped (and hence unborrowed) in reverse order. So 'a will necessarily be dropped before its owner, hence it's shorter than 'static.

As you can see it complains that it's dropped at the end of main() even though it should be borrowed for 'static. If this was an owned value it would NOT be dropped at main() since it would be moved into the function on call.

Nothing surprising here.

> &a can live up to the end of the application

Nope. Imagine spawning a thread and passing &a but keeping 'a' in your main thread.

> bow out of this conversation thread I'm afraid

Welp I did what I could.


> a can live up to the end of the application. &a can live up to the end of the application.

Nope, a reference to a stack frame can't live up to the end of the application. The stack frame gets deallocated and the referent ceases to exist; therefore the reference you're creating in your linked example doesn't outlive 'static. `main` is not an exception to this in Rust.


> ...but it can also have values in it which are not 'static.

I don't think that's right. It can only have references which live at least as long as 'static does (or longer, but 'static is the longest so...)


I think he means owned values (notice he didn't say "other references") But actually... owned values are bound by 'static!




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: