-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
rustc: Remove all "consider using an explicit lifetime parameter" suggestions #37057
Conversation
I feel like I've found these helpful many more times than they've been wrong, but the compiler giving wrong advice is indeed a frustrating experience that could cause users to believe that the borrow rules are 'not worth it,' 'not good enough,' 'not correct,' or some other negative thing. Perhaps in the long term when the compiler could rerun the borrowck pass with the explicit annotations, recurring as necessary (and accumulating all of them to make a single suggestion), and only make the suggestion if the resulting code passes? To provide a counterargument even to that change (though I think the negative experiences overwhelm this), in complicated (but safe) lifetime wrangling code, I have followed the compiler's suggestions to find the lifetime error I actually needed to solve. |
@withoutboats - do you think it can be fixed rather than being removed? That is, is there a heuristic for generally when the notes are helpful? Being wrong to me just sounds like a net loss, but if there are times we can detect that they'll be useful and only display them then, that seems like a better improvement than pulling it out altogether |
I think I agree with removing this code. It's bitrotted and dates from a time when the language was quite different (e.g., no I know that I have definitely found these suggestions helpful on many occasions. One particularly useful thing they can do is to highlight where there are elided lifetime parameters that you did not know about that are causing you grief. |
I gave a sort of "high-level" idea of where I have found them useful, and I know that anecdotally people have told me that they like them, but I think they also mislead a lot. It's a bad sign that e.g. when I see one I usually just ignore it, or I find it's quite common that it's either showing me the same signature I have or making some other non-actionable suggestion. I wish I had more specific examples at hand but I don't. Perhaps if we turn them off we will start to accumulate some, though. =) That said, I do suspect we could identify the cases where it might be wrong and avoid them. But also the code is (as I wrote before) sort of old and done in a weird way, and I'd rather have a cleaner start. Though I'm not sure what's better. Right now it crawls the HIR and makes modifications and then pretty-prints it, as I recall. We might be able to just do some thing where it finds the parameters whose types can be changed and does a |
I'd like a bit wider feedback here. cc @rust-lang/docs @rust-lang/compiler |
Sometimes these give good suggestions, but it seems to be at 50% or less for me. I would rather they were fixed rather than thrown out, but I guess throwing out seems like an improvement over the status quo. |
I'm in favor for a deletion for now. |
I can sort of read it to get the bounds I want. Maybe we should just dump some of these bounds on the user directly? It does tell me when I get a type parameter missing in a method signature and inferred to something random. |
☔ The latest upstream changes (presumably #37269) made this pull request unmergeable. Please resolve the merge conflicts. |
I’m in of a similar mind as @withoutboats: I’ve had a multiple cases where suggestion from this class helped me out to figure out the problem at hand. While the solution in most cases ended up not being exactly what suggestion was telling me to use, it often helped me to understand what the compiler thought under the hood and figure out how my code was wrong easier. |
I feel like what all of us experienced users are saying is: the suggestions per se are not helpful, but they expose helpful information. Seems like we should replace this with something more targeted that does expose that information. I'd feel much better about removing if we had someone dedicated to doing that work --- and I'd love to work with them, "I have thoughts" -- but I am not sure what to do in the interim. I definitely dislike giving misleading or wrong suggestions. |
As a starting point, more examples where the messages were helpful would be good. |
@nikomatsakis Lowest cost change (that can be backported to beta) would be adding "This is what a working signature might look like (please report incorrect suggestions at https://github.com/rust-lang/lang/issues):". |
@nikomatsakis @jonathandturner See #37363 for an example of a case with an easy fix. |
Had some brief discussion with @brson on IRC. I think both of us are still inclined to remove, unless someone wants to take up the active task of improving. That said, I suspect there are some simple heuristics that would guide us to better suggestions. It would help if we had a corpus of actual errors people encounter in practice. My biggest hesitation here results from the fact that the base errors do tend to be the worst we give. Another place where a corpus would be ultra-helpful! Most of my attempts to think about improvements get stuck around here, trying to gather up data. |
My thoughts:
|
+1 on "remove and file an issue to follow-up with better design" |
👍 to what Jonathan said On Thu, Nov 3, 2016, 07:41 Jonathan Turner notifications@github.com wrote:
Jeremiah Peschka |
I agree with @steveklabnik. I think this feature as is should be removed; I just think suggesting explicit annotations is a good idea to pursue and we shouldn't take the position that we tried this and it doesn't work. (What I've found rather frustrating recently is that it will suggest adding lifetime annotations to impls of foreign traits. Come on compiler, you know I can't do that.) |
#37481 should fix that. Also, rewording the message to make the compiler seem less confident in its suggestions would replace user pain with bug reports along the lines of "compiler suggestion didn't work". |
Sounds like this is leaning towards removal, @brson want to rebase and @nikomatsakis want to r+? |
@alexcrichton yeah, I've been vacillating on how to decide how to reach a decision here. =) But it does seem like the majority of people are in favor of removal, so I'm still inclined to go that way. |
I'm worried about the potential fallaciousness of "a redesign from scratch won't have these problems". |
I am generally able to read the desired bounds out of the suggestions. I think that just dumping the transitive reduction of the requested lifetime bounds would be OK. |
So ok I am quite frustrated that this PR is still open. We need to make a decision. Let me summarize as best I can the arguments on either side: In favor of removal:
In favor of keeping:
Some concerns:
Possible courses of action:
My ideal course of action here would probably be to back out the existing code, but identify someone who is motivated to work on improving it (I'd be happy to mentor). This overlaps with the exiting complaints about lifetime inference errors. Seem like a reasonable summary? |
…gestions These give so many incorrect suggestions that having them is detrimental to the user experience. The compiler should not be suggesting changes to the code that are wrong - it is infuriating: not only is the compiler telling you that _you don't understand_ borrowing, _the compiler itself_ appears to not understand borrowing. It does not inspire confidence.
Tests pass locally. |
@bors r+ |
📌 Commit a2735c0 has been approved by |
OK, this means I have to get serious about planning out improved region errors. People who contributed to this discussion: if you can please add candidate errors to this etherpad, I would appreciate it. I have been trying to get a good categorization of different classes of errors that occur. |
Testing something, but I plan to reopen |
Yup, originally the PR contained the character "…" which apparently caused homu to choke. I've now updated the PR description to have three literal dots. wtf homu |
@bors: r=nikomatsakis |
💡 This pull request was already approved, no need to approve it again.
|
📌 Commit a2735c0 has been approved by |
rustc: Remove all "consider using an explicit lifetime parameter" suggestions These give so many incorrect suggestions that having them is detrimental to the user experience. The compiler should not be suggesting changes to the code that are wrong - it is infuriating: not only is the compiler telling you that _you don't understand_ borrowing, _the compiler itself_ appears to not understand borrowing. It does not inspire confidence. r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
A recent Stack Overflow question was improved when we added the "consider using an explicit lifetime parameter as shown" error. I thought that the OP wasn't reading the error messages, but perhaps they were simply using beta / nightly (although the timeline gets complicated). I'm pretty sure this hint is an example of @nikomatsakis comment about "locally right, globally wrong", but making the suggested change in OP's original code helped shift the error message to something else that might be more immediately resolvable. I've removed external dependencies from that example and added it to the etherpad. I'm sad to see this hint going away, and I look forward to the replacement! |
@shepmaster - the plan is to replace it with something better. If you have ideas for improvement, I'd love to hear them (since it probably falls to me to help design the replacement) |
@shepmaster thanks for adding that; I definitely want to get started on some replacements right away. |
…felix Report full details of inference errors When the old suggestion machinery was removed by @brson in rust-lang#37057, it was not completely removed. There was a bit of code that had the job of going through errors and finding those for which suggestions were applicable, and it remained, causing us not to emit the full details of such errors. This PR removes that. I've also added various lifetime tests to the UI test suite (so you can also see the before/after there). I have some concrete thoughts on how to improve these cases and am planning on writing those up in some mentoring issues (@cengizio has expressed interest in working on those changes, so I plan to work with him on it, at least to start). cc @jonathandturner
Version 1.16.0 (2017-03-16) =========================== Language -------- * Lifetimes in statics and consts default to `'static`. [RFC 1623] * [The compiler's `dead_code` lint now accounts for type aliases][38051]. * [Uninhabitable enums (those without any variants) no longer permit wildcard match patterns][38069] * [Clean up semantics of `self` in an import list][38313] * [`Self` may appear in `impl` headers][38920] * [`Self` may appear in struct expressions][39282] Compiler -------- * [`rustc` now supports `--emit=metadata`, which causes rustc to emit a `.rmeta` file containing only crate metadata][38571]. This can be used by tools like the Rust Language Service to perform metadata-only builds. * [Levenshtein based typo suggestions now work in most places, while previously they worked only for fields and sometimes for local variables][38927]. Together with the overhaul of "no resolution"/"unexpected resolution" errors (#[38154]) they result in large and systematic improvement in resolution diagnostics. * [Fix `transmute::<T, U>` where `T` requires a bigger alignment than `U`][38670] * [rustc: use -Xlinker when specifying an rpath with ',' in it][38798] * [`rustc` no longer attempts to provide "consider using an explicit lifetime" suggestions][37057]. They were inaccurate. Stabilized APIs --------------- * [`VecDeque::truncate`] * [`VecDeque::resize`] * [`String::insert_str`] * [`Duration::checked_add`] * [`Duration::checked_sub`] * [`Duration::checked_div`] * [`Duration::checked_mul`] * [`str::replacen`] * [`str::repeat`] * [`SocketAddr::is_ipv4`] * [`SocketAddr::is_ipv6`] * [`IpAddr::is_ipv4`] * [`IpAddr::is_ipv6`] * [`Vec::dedup_by`] * [`Vec::dedup_by_key`] * [`Result::unwrap_or_default`] * [`<*const T>::wrapping_offset`] * [`<*mut T>::wrapping_offset`] * `CommandExt::creation_flags` * [`File::set_permissions`] * [`String::split_off`] Libraries --------- * [`[T]::binary_search` and `[T]::binary_search_by_key` now take their argument by `Borrow` parameter][37761] * [All public types in std implement `Debug`][38006] * [`IpAddr` implements `From<Ipv4Addr>` and `From<Ipv6Addr>`][38327] * [`Ipv6Addr` implements `From<[u16; 8]>`][38131] * [Ctrl-Z returns from `Stdin.read()` when reading from the console on Windows][38274] * [std: Fix partial writes in `LineWriter`][38062] * [std: Clamp max read/write sizes on Unix][38062] * [Use more specific panic message for `&str` slicing errors][38066] * [`TcpListener::set_only_v6` is deprecated][38304]. This functionality cannot be achieved in std currently. * [`writeln!`, like `println!`, now accepts a form with no string or formatting arguments, to just print a newline][38469] * [Implement `iter::Sum` and `iter::Product` for `Result`][38580] * [Reduce the size of static data in `std_unicode::tables`][38781] * [`char::EscapeDebug`, `EscapeDefault`, `EscapeUnicode`, `CaseMappingIter`, `ToLowercase`, `ToUppercase`, implement `Display`][38909] * [`Duration` implements `Sum`][38712] * [`String` implements `ToSocketAddrs`][39048] Cargo ----- * [The `cargo check` command does a type check of a project without building it][cargo/3296] * [crates.io will display CI badges from Travis and AppVeyor, if specified in Cargo.toml][cargo/3546] * [crates.io will display categories listed in Cargo.toml][cargo/3301] * [Compilation profiles accept integer values for `debug`, in addition to `true` and `false`. These are passed to `rustc` as the value to `-C debuginfo`][cargo/3534] * [Implement `cargo --version --verbose`][cargo/3604] * [All builds now output 'dep-info' build dependencies compatible with make and ninja][cargo/3557] * [Build all workspace members with `build --all`][cargo/3511] * [Document all workspace members with `doc --all`][cargo/3515] * [Path deps outside workspace are not members][cargo/3443] Misc ---- * [`rustdoc` has a `--sysroot` argument that, like `rustc`, specifies the path to the Rust implementation][38589] * [The `armv7-linux-androideabi` target no longer enables NEON extensions, per Google's ABI guide][38413] * [The stock standard library can be compiled for Redox OS][38401] * [Rust has initial SPARC support][38726]. Tier 3. No builds available. * [Rust has experimental support for Nvidia PTX][38559]. Tier 3. No builds available. * [Fix backtraces on i686-pc-windows-gnu by disabling FPO][39379] Compatibility Notes ------------------- * [Uninhabitable enums (those without any variants) no longer permit wildcard match patterns][38069] * In this release, references to uninhabited types can not be pattern-matched. This was accidentally allowed in 1.15. * [The compiler's `dead_code` lint now accounts for type aliases][38051]. * [Ctrl-Z returns from `Stdin.read()` when reading from the console on Windows][38274] * [Clean up semantics of `self` in an import list][38313] [37057]: rust-lang/rust#37057 [37761]: rust-lang/rust#37761 [38006]: rust-lang/rust#38006 [38051]: rust-lang/rust#38051 [38062]: rust-lang/rust#38062 [38062]: rust-lang/rust#38622 [38066]: rust-lang/rust#38066 [38069]: rust-lang/rust#38069 [38131]: rust-lang/rust#38131 [38154]: rust-lang/rust#38154 [38274]: rust-lang/rust#38274 [38304]: rust-lang/rust#38304 [38313]: rust-lang/rust#38313 [38314]: rust-lang/rust#38314 [38327]: rust-lang/rust#38327 [38401]: rust-lang/rust#38401 [38413]: rust-lang/rust#38413 [38469]: rust-lang/rust#38469 [38559]: rust-lang/rust#38559 [38571]: rust-lang/rust#38571 [38580]: rust-lang/rust#38580 [38589]: rust-lang/rust#38589 [38670]: rust-lang/rust#38670 [38712]: rust-lang/rust#38712 [38726]: rust-lang/rust#38726 [38781]: rust-lang/rust#38781 [38798]: rust-lang/rust#38798 [38909]: rust-lang/rust#38909 [38920]: rust-lang/rust#38920 [38927]: rust-lang/rust#38927 [39048]: rust-lang/rust#39048 [39282]: rust-lang/rust#39282 [39379]: rust-lang/rust#39379 [`<*const T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset [`<*mut T>::wrapping_offset`]: https://doc.rust-lang.org/std/primitive.pointer.html#method.wrapping_offset [`Duration::checked_add`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_add [`Duration::checked_div`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_div [`Duration::checked_mul`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_mul [`Duration::checked_sub`]: https://doc.rust-lang.org/std/time/struct.Duration.html#method.checked_sub [`File::set_permissions`]: https://doc.rust-lang.org/std/fs/struct.File.html#method.set_permissions [`IpAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_ipv4 [`IpAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.IpAddr.html#method.is_ipv6 [`Result::unwrap_or_default`]: https://doc.rust-lang.org/std/result/enum.Result.html#method.unwrap_or_default [`SocketAddr::is_ipv4`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv4 [`SocketAddr::is_ipv6`]: https://doc.rust-lang.org/std/net/enum.SocketAddr.html#method.is_ipv6 [`String::insert_str`]: https://doc.rust-lang.org/std/string/struct.String.html#method.insert_str [`String::split_off`]: https://doc.rust-lang.org/std/string/struct.String.html#method.split_off [`Vec::dedup_by_key`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by_key [`Vec::dedup_by`]: https://doc.rust-lang.org/std/vec/struct.Vec.html#method.dedup_by [`VecDeque::resize`]: https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.resize [`VecDeque::truncate`]: https://doc.rust-lang.org/std/collections/vec_deque/struct.VecDeque.html#method.truncate [`str::repeat`]: https://doc.rust-lang.org/std/primitive.str.html#method.repeat [`str::replacen`]: https://doc.rust-lang.org/std/primitive.str.html#method.replacen [cargo/3296]: rust-lang/cargo#3296 [cargo/3301]: rust-lang/cargo#3301 [cargo/3443]: rust-lang/cargo#3443 [cargo/3511]: rust-lang/cargo#3511 [cargo/3515]: rust-lang/cargo#3515 [cargo/3534]: rust-lang/cargo#3534 [cargo/3546]: rust-lang/cargo#3546 [cargo/3557]: rust-lang/cargo#3557 [cargo/3604]: rust-lang/cargo#3604 [RFC 1623]: https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md
These give so many incorrect suggestions that having them is
detrimental to the user experience. The compiler should not be
suggesting changes to the code that are wrong - it is infuriating: not
only is the compiler telling you that you don't understand borrowing,
the compiler itself appears to not understand borrowing. It does not
inspire confidence.
r? @nikomatsakis