Fix suggestions for borrowed fields - #17661
Conversation
|
Thanks for the pull request. A reviewer will take a look after it receives 2 community reviews. In the meantime, we would highly appreciate if you could try to review any of PRs waiting on community reviews. |
| // For field access, borrowing the scrutinee (`&self.field`) can keep the borrow alive | ||
| // after the `if` under legacy borrow checking, conflicting with a later mutation | ||
| // (#16182). A `ref` or `ref mut` binding instead | ||
| // borrows only the matched field value. | ||
| let (binding_prefix, borrow_prefix) = match (as_ref_kind, &unwrappable.local) { |
There was a problem hiding this comment.
since there seems to be a different desired behaviour for the lint based on polonius being enabled or not, can we switch on this and provide the best possible lint output?
There was a problem hiding this comment.
The suggestion now switches on sess.opts.unstable_opts.polonius. For a field-access scrutinee:
| polonius (nightly default) | -Zpolonius=off |
|---|---|
if let Some(<item>) = &self.option |
if let Some(ref <item>) = self.option |
&self.option evaluates the borrow before the match, so under NLL it can outlive the if and clash with a later mutation (#16182). Polonius doesn't have that limitation. Only the NLL path needs the ref fallback, and because the flag comes off the session, stable gets ref while nightly gets the nicer form. Plain locals are unchanged.
Tests are split the same way. simple_conditionals.rs asserts the & form; a new simple_conditionals_polonius_off.rs carries //@compile-flags: -Zpolonius=off and asserts ref. Both files also have companion methods written the way the lint suggests, so if a suggestion doesn't borrow-check under its own mode, the test file stops compiling.
Fixes #16182.
unnecessary_unwrapsuggests borrowing the scrutinee when it fires on a field access checked withis_some()/is_ok()and unwrapped throughas_ref()/as_mut():Evaluating that scrutinee borrows
self.optionbefore matching. Under the legacy borrow checker, the borrow can remain live after theifand conflict with a later mutation ofself.option, producing E0502.Current nightly’s default Polonius mode accepts the old form, while
-Zpolonius=offreproduces the reported error. The equivalentrefform works with both borrow checkers, so field accesses now get:Plain locals retain the existing
&and&mutsuggestions. The conflicting&mut Option<_>or&mut Result<_, _>parameter shape is not linted because its checked receiver type is a reference rather than theOptionorResultADT.The UI tests cover shared and mutable
Optionaccess, bothResultvariants, tuple fields, and multi-level field access.changelog: Fix [
unnecessary_unwrap]: userefbindings when suggestingif letfor borrowed fields