Live data from Hacker News

Common Rust Lifetime Misconceptions (2020)

github.com

41–50 of 89 posts

Re: Common Rust Lifetime Misconceptions (2020)

#41

Once I discovered ‘static was the subtype of all lifetimes rather than the super things began clicking for me.

Could you elaborate? I find this unintuitive.

I am not familiar with the formal type theory, but this one is intuitive if you view it this way:

1. When A is a subtype of B, it means A can be used as B (a Teacher can be used by any function that accepts a Human).

2. static lifetime lives longer any other lifetimes, so it can be used as other lifetimes.

Re: Common Rust Lifetime Misconceptions (2020)

#42
post #31

Incredible. I never held the quoted misconception about `T: '*`, but I didn't understand it. It was a known unknown - I simply applied it when told to do so. This is the first time someone has explained it an understandable way, I guess the implications (it's a ref of that lifetime or an owned) are a better explanation than the technical (T is bounded by the lifetime).

Same. I wrote a lot of Rust, even some open source libraries that are being used and generally feel comfortable using it but I learned a lot out of this very nice write-up.

Re: Common Rust Lifetime Misconceptions (2020)

#43

How I bail myself out of Rust lifetime problems as somebody who probably learned Rust the wrong way (by just trying to build stuff as if it were C/node.js and run into problems instead of slowing down + reading): 1. .clone() / .to_owned() 1. String -> vs &String/&str with & borrow 1. lazy_static / OnceCell + Lazy / OnceLock 1. Arc > with lots of .lock(). What would start off as like NULL in Java/C is Arc >> and you h…

Good advice, though I'd recommend Rc > instead of Arc > if you're not sharing the data between threads, to avoid synchronization overhead. I use Arc pretty rarely.

The overhead of an uncontested lock is not much more than a memory operation but it allows you to be able to use the same code in threaded context in tokio async which is a huge benefit. Unless you need the optimization (i.e. you profiled and determined that Arc in a hot loop is slowing you down) I think it's fine to use Arc in general.

Re: Common Rust Lifetime Misconceptions (2020)

#44

Earlier quoted context omitted.

Mind expanding on this? The nomicon describes &’a T where both ‘a’ and ‘T’ are covariant. I thought I had a clear picture but now I’m confused. https://doc.rust-lang.org/nomicon/subtyping.html#variance

Here is the original GitHub issue on the question: https://github.com/rust-lang/rust/issues/15699 And an RFC by some people that felt frustrated by this arguably implementation-centric view that kind of lost steam: https://github.com/rust-lang/rfcs/issues/391 Intuitively, the bottom lifetime should the one that is uninhabited, which would be a lifetime with no extent rather than 'static.

Interesting, thanks for sharing!

Re: Common Rust Lifetime Misconceptions (2020)

#45

How I bail myself out of Rust lifetime problems as somebody who probably learned Rust the wrong way (by just trying to build stuff as if it were C/node.js and run into problems instead of slowing down + reading): 1. .clone() / .to_owned() 1. String -> vs &String/&str with & borrow 1. lazy_static / OnceCell + Lazy / OnceLock 1. Arc > with lots of .lock(). What would start off as like NULL in Java/C is Arc >> and you h…

This is the way. The real misconception of lifetimes is that people have to use them often. You don’t unless your are writing libraries or system code.

Re: Common Rust Lifetime Misconceptions (2020)

#46

Earlier quoted context omitted.

Good advice, though I'd recommend Rc > instead of Arc > if you're not sharing the data between threads, to avoid synchronization overhead. I use Arc pretty rarely.

The overhead of an uncontested lock is not much more than a memory operation but it allows you to be able to use the same code in threaded context in tokio async which is a huge benefit. Unless you need the optimization (i.e. you profiled and determined that Arc in a hot loop is slowing you down) I think it's fine to use Arc in general.

`RefCell` does have one big advantage, though: it'll panic instead of deadlock for reentrant borrow.

Re: Common Rust Lifetime Misconceptions (2020)

#47

How I bail myself out of Rust lifetime problems as somebody who probably learned Rust the wrong way (by just trying to build stuff as if it were C/node.js and run into problems instead of slowing down + reading): 1. .clone() / .to_owned() 1. String -> vs &String/&str with & borrow 1. lazy_static / OnceCell + Lazy / OnceLock 1. Arc > with lots of .lock(). What would start off as like NULL in Java/C is Arc >> and you h…

This is how my team writes production Rust code. Knowing which one to use and when is important, but there's nothing wrong with using the tools available to you. Non-lexical lifetimes are, in my experience, pretty uncommon in most non-library code. You don't really need them until you really need them.

Non-lexical lifetimes are, in my experience, pretty uncommon in most non-library code.

To avoid confusing the newcomers: lifetimes are always non-lexical (see [1] for the pedantic details.) I suppose you meant that explicit lifetime annotations are pretty uncommon, which is not wrong.

[1] https://blog.rust-lang.org/2022/08/05/nll-by-default.html

Re: Common Rust Lifetime Misconceptions (2020)

#48
post #21

About #10: > because to unify them at this point would be a breaking change Couldn't they change this in a future edition without breaking older editions?

Technically yes, but editions are more like different "flavors" of Rust than actual breaking changes. A 2021 crate is supposed to be able to import a 2018 crate, likewise for 2015 and 2024. Because they all need to work together, edition changes still need to be somewhat compatible with older versions. Because you can pass closures into functions across crate boundaries, which requires consistent lifetime semantics,…

As far as I can tell, this change is compatible with other editions. Closures can already be higher-ranked, and changing closures to be higher-ranked will work with existing editions.

A more problematic thing is that `cargo fix --edition` should be able to transform existing code to the same meaning in a new edition, so there should be a way to opt-in for the old behavior.

Re: Common Rust Lifetime Misconceptions (2020)

#49

How I bail myself out of Rust lifetime problems as somebody who probably learned Rust the wrong way (by just trying to build stuff as if it were C/node.js and run into problems instead of slowing down + reading): 1. .clone() / .to_owned() 1. String -> vs &String/&str with & borrow 1. lazy_static / OnceCell + Lazy / OnceLock 1. Arc > with lots of .lock(). What would start off as like NULL in Java/C is Arc >> and you h…

> who probably learned Rust the wrong way (by just trying to build stuff as if it were C/node.js and run into problems instead of slowing down + reading):

This is the right way to learn. I'm quite familiar with lifetimes and whatnot, but when I didn't bother with them much at all when learning - I just "clone"'d.

This allowed me to learn 95% of the language, and then once I did that, learn the last 5% (lifetimes).

Highly recommend.

Re: Common Rust Lifetime Misconceptions (2020)

#50

About #10: > because to unify them at this point would be a breaking change Couldn't they change this in a future edition without breaking older editions?

Wouldn't fixing 10 just mean allowing things that were previously not allowed? That's not a breaking change. What am I missing?

No it will not:

    fn requires_static(_: &'static str) {}
    
    let long_lifetime: &'static str = "";
    let closure = |_input: &str| -> &str { long_lifetime };
    let short_lifetime = &String::new();
    requires_static(closure(short_lifetime));
This code compiles currently as the returned `&str` is inferred to be `&'static str` because this is what it actually returns, but with #10 fixed it will not because lifetime elision rules say that the lifetime of the output is the same as the lifetime of the input.
Post reply on HN