Rollup merge of #152587 - lqd:tiny-things, r=jackh726

A couple of tiny polonius things

Here's a couple of tiny things I had ready to go @jackh726
- a tiny cleanup to avoid round-tripping through `Location`s to check for liveness, since we're already working with points
- while I was there, I fixed the doc which wasn't showing up properly (maybe a rustdoc or bootstrap bug when we build locally or during dist, either way, both don't show up correctly linked most of the time) for `PointIndex`es.
- and in the second commit slightly expand test coverage with [an example](https://internals.rust-lang.org/t/get-mut-map-back-from-entry-api/24003) that would have needed stdlib changes (cc author @Darksonn for visibility here)

More soon.

r? @jackh726
This commit is contained in:
Jacob Pratt
2026-02-13 22:26:36 -05:00
committed by GitHub
4 changed files with 48 additions and 8 deletions
+1 -2
View File
@@ -182,8 +182,7 @@ fn on_node_traversed(&mut self, loan: BorrowIndex, node: LocalizedNode) {
//
// FIXME: analyze potential unsoundness, possibly in concert with a borrowck
// implementation in a-mir-formality, fuzzing, or manually crafting counter-examples.
let location = self.liveness.location_from_point(node.point);
if self.liveness.is_live_at(node.region, location) {
if self.liveness.is_live_at_point(node.region, node.point) {
self.live_loans.insert(node.point, loan);
}
}
@@ -131,9 +131,17 @@ pub(crate) fn add_all_points(&mut self, region: RegionVid) {
}
}
/// Returns whether `region` is marked live at the given `location`.
/// Returns whether `region` is marked live at the given
/// [`location`][rustc_middle::mir::Location].
pub(crate) fn is_live_at(&self, region: RegionVid, location: Location) -> bool {
let point = self.location_map.point_from_location(location);
self.is_live_at_point(region, point)
}
/// Returns whether `region` is marked live at the given
/// [`point`][rustc_mir_dataflow::points::PointIndex].
#[inline]
pub(crate) fn is_live_at_point(&self, region: RegionVid, point: PointIndex) -> bool {
if let Some(points) = &self.points {
points.row(region).is_some_and(|r| r.contains(point))
} else {
@@ -35,8 +35,21 @@ LL | | }
LL | | }
| |_____- returning this value requires that `*map` is borrowed for `'r`
error[E0499]: cannot borrow `*map` as mutable more than once at a time
--> $DIR/nll-problem-case-3-issue-21906.rs:45:41
|
LL | fn get_priority_mut_entry<'a, K, V>(
| -- lifetime `'a` defined here
...
LL | match map.entry(key1) {
| --- first mutable borrow occurs here
LL | Entry::Occupied(occupied) => Some(occupied.into_mut()),
| ------------------------- returning this value requires that `*map` is borrowed for `'a`
LL | Entry::Vacant(_vacant) => match map.entry(key2) {
| ^^^ second mutable borrow occurs here
error[E0499]: cannot borrow `*self` as mutable more than once at a time
--> $DIR/nll-problem-case-3-issue-21906.rs:44:21
--> $DIR/nll-problem-case-3-issue-21906.rs:64:21
|
LL | fn two(&mut self) -> &i32 {
| - let's call the lifetime of this reference `'1`
@@ -48,7 +61,7 @@ LL | return k;
| - returning this value requires that `*self` is borrowed for `'1`
error[E0502]: cannot borrow `x.data` as immutable because it is also borrowed as mutable
--> $DIR/nll-problem-case-3-issue-21906.rs:62:22
--> $DIR/nll-problem-case-3-issue-21906.rs:82:22
|
LL | fn foo(x: &mut Foo) -> Option<&mut i32> {
| - let's call the lifetime of this reference `'1`
@@ -61,7 +74,7 @@ LL | println!("{:?}", x.data);
| ^^^^^^ immutable borrow occurs here
error[E0499]: cannot borrow `*vec` as mutable more than once at a time
--> $DIR/nll-problem-case-3-issue-21906.rs:77:9
--> $DIR/nll-problem-case-3-issue-21906.rs:97:9
|
LL | fn f(vec: &mut Vec<u8>) -> &u8 {
| - let's call the lifetime of this reference `'1`
@@ -75,7 +88,7 @@ LL | vec.push(10);
| ^^^ second mutable borrow occurs here
error[E0502]: cannot borrow `*vec` as immutable because it is also borrowed as mutable
--> $DIR/nll-problem-case-3-issue-21906.rs:78:9
--> $DIR/nll-problem-case-3-issue-21906.rs:98:9
|
LL | fn f(vec: &mut Vec<u8>) -> &u8 {
| - let's call the lifetime of this reference `'1`
@@ -88,7 +101,7 @@ LL | n
LL | vec.last().unwrap()
| ^^^ immutable borrow occurs here
error: aborting due to 6 previous errors
error: aborting due to 7 previous errors
Some errors have detailed explanations: E0499, E0502.
For more information about an error, try `rustc --explain E0499`.
@@ -29,6 +29,26 @@ fn from_the_rfc<'r, K: Hash + Eq + Copy, V: Default>(
}
}
// A variant that's similar to the RFC example above, but using the entry API, and requested in
// https://internals.rust-lang.org/t/get-mut-map-back-from-entry-api/24003
fn get_priority_mut_entry<'a, K, V>(
map: &'a mut HashMap<K, V>,
key1: K,
key2: K,
) -> Option<&'a mut V>
where
K: Eq + Hash,
{
use std::collections::hash_map::Entry;
match map.entry(key1) {
Entry::Occupied(occupied) => Some(occupied.into_mut()),
Entry::Vacant(_vacant) => match map.entry(key2) {
Entry::Occupied(occupied2) => Some(occupied2.into_mut()),
Entry::Vacant(_) => None,
},
}
}
// MCVE 1 from issue #21906
struct A {
a: i32,