3 ms·
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?
by ForkMeOnTinder 3y ago
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?
- BD103 3y agoTechnically 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, I find it unlikely that this will be implemented.
- afdbcreid 3y agoAs 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.
- tadfisher 3y agoA new edition is not a free pass to break source compatibility; it's more like a fire axe hidden behind breakable glass. You really, really want to avoid breaking changes because your users will now have to know about the difference between the compiler editions used by each of their projects. In short, yes, but be very wary.
- drewtato 3y agoMost likely yes. However, if you don't specify the argument type, it compiles fine. It's rare that you need to specify argument or return types on a closure, so it's not actually a large issue.
- Buttons840 3y agoWouldn't fixing 10 just mean allowing things that were previously not allowed? That's not a breaking change. What am I missing?
- afdbcreid 3y agoNo 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.
- brabel 3y agoHm, in this case it's actually nice that this works because there's nothing unsafe or unexpected going on.