Repository navigation
Borrow checking for static methods became more strict #100725
Description
Activity
- addedC-bugCategory: This is a bug.Category: This is a bug.regression-untriagedUntriaged performance or correctness regression.Untriaged performance or correctness regression.
on Aug 18, 2022 - addedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.and removedregression-untriagedUntriaged performance or correctness regression.Untriaged performance or correctness regression.
on Aug 18, 2022 Yes, that’s definitely #98835, but an interesting new case AFAICT.
Edit: On second thought, it’s slightly less interesting/new than I initially thought. See this comment.
So for some context/explanation, the compiler used to (arguably somewhat “incorrectly”) act more like as if the closure was
byte_list.iter_mut().find_map(|item| { Bigger::<'_>::other(item); Some(()) });
instead of
byte_list.iter_mut().find_map(|item| { Bigger::<'a>::other(item); // <- expansion of the `Self::other` Some(()) });
and hence accepted
itemto be shorter-lived than'a.
To fix the code, you’ll just need to replace
Self::otherbyBigger::otherto remove that overly-specific and constraining lifetime'a.So for some context/explanation, the compiler used to (arguably somewhat “incorrectly”) act more like as if the closure was
In fact, I am glad that the new version of the compiler flagged that error. That helped me into fixing an unnecessary overly-specific lifetime constraint that slipped through the code review process.
I've reported this as the regression worried me.
I've reported this as the regression worried me.
Rightfully so, better be safe than sorry.
In fact, I am glad that the new version of the compiler flagged that error.
FYI, I don’t think removing the compiler error entirely will happen, so even if this kind of regression is addressed, the usefulness of the compiler will not be reduced; as you noted it’s a useful error message, (and also the new check is there to prevent lots of new cases that would otherwise compiler successfully with the newly enabled full NLL-only borrow checking). AFAICT, the only thing still up to discussion is whether or not perhaps the new error should initially only be a lint. Possibly deny-by-default (so it’ll look a lot like an error, but not break downstream code depending on broken crates), and most definitely a future-incompatibility lint, so you (or your dependencies) cannot accidentally (i.e. without noticing it) write new code with such lifetime-annotation-inaccuracies that might be broken later if we do make it a hard error later. (Perhaps also with improved diagnostics to help fixing the issue.)
error output under #100976
--> /tmp/tto6.rs:15:9 | 8 | impl<'a> Bigger<'a> { | -- lifetime `'a` defined here 9 | pub fn get_addr(byte_list: &'a mut Vec<u8>) -> &mut u8 { 10 | byte_list.iter_mut().find_map(|item| { | -------------------- first mutable borrow occurs here 11 | Self::other(item); // replace with `Bigger` | ----------- type annotation requires that `*byte_list` is borrowed for `'a` ... 15 | byte_list.push(0); | ^^^^^^^^^^^^^^^^^ second mutable borrow occurs here | help: you can remove unnecessary lifetime annotations here --> /tmp/tto6.rs:11:13 | 11 | Self::other(item); // replace with `Bigger` | ^^^^^^^^^^^ = help: consider replacing `Self` with `Bigger`
WG-prioritization assigning priority (Zulip discussion).
@rustbot label -I-prioritize +P-high
- addedP-highHigh priorityHigh priorityand removedI-prioritizeIssue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}Issue needs a team member to assess the impact. Will be replaced by P-{low,medium,high,critical}
on Aug 25, 2022 - addedregression-from-stable-to-betaPerformance or correctness regression from stable to beta.Performance or correctness regression from stable to beta.and removedregression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.Performance or correctness regression from stable to nightly.
on Aug 25, 2022 - addedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Sep 8, 2022 - addedregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.Performance or correctness regression from one stable version to another.and removedregression-from-stable-to-betaPerformance or correctness regression from stable to beta.Performance or correctness regression from stable to beta.
on Sep 22, 2022 Visited during P-high 2022 Q3 review.
We agreed that this regression was expected, and the answer here is improving the diagnostics.
Also, we note that this should be resolved when PR #100976 lands.
We're lowering the priority from P-high to P-medium.
@rustbot label: -P-high +P-medium
- addedP-mediumMedium priorityMedium priorityand removedP-highHigh priorityHigh priority
on Oct 28, 2022 Also reassigning to T-types
@rustbot label: -T-compiler +T-types
- addedT-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.and removedT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Oct 28, 2022
Code
I tried this code:
I expected to see this happen: I don't know what should be the behavior. Looks like it all boils down to what is going to be
'awithinBigger::<'a>::other. In stable version of Rust, the code was accepted.Instead, this happened: Using nightly version of the compiler a borrow checker error happened.
Version it worked on
It most recently worked on: cargo 1.63.0 (fd9c4297c 2022-07-01) / rustc 1.63.0 (4b91a6e 2022-08-08)
Version with regression
rustc --version --verbose: