From 64d143326f222ef477044d846e7e8f09ac6d6a3a Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Tue, 11 Mar 2025 22:57:01 +0200 Subject: [PATCH 1/2] Refactor pick2_mut & pick3_mut to use get_disjoint_mut --- compiler/rustc_index/src/slice.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index f17ea9e4b59ad..6e28d1ccf279f 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -120,13 +120,12 @@ impl IndexSlice { pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { let (ai, bi) = (a.index(), b.index()); assert!(ai != bi); + let len = self.raw.len(); + assert!(ai < len && bi < len); - if ai < bi { - let (c1, c2) = self.raw.split_at_mut(bi); - (&mut c1[ai], &mut c2[0]) - } else { - let (c2, c1) = self.pick2_mut(b, a); - (c1, c2) + match self.raw.get_disjoint_mut([ai, bi]) { + Ok([a, b]) => (a, b), + Err(_) => panic!("Can't get mutable references"), } } @@ -139,8 +138,11 @@ impl IndexSlice { assert!(ai != bi && bi != ci && ci != ai); let len = self.raw.len(); assert!(ai < len && bi < len && ci < len); - let ptr = self.raw.as_mut_ptr(); - unsafe { (&mut *ptr.add(ai), &mut *ptr.add(bi), &mut *ptr.add(ci)) } + + match self.raw.get_disjoint_mut([ai, bi, ci]) { + Ok([a, b, c]) => (a, b, c), + Err(_) => panic!("Can't get mutable references"), + } } #[inline] From 7398b39a0bfae6c778379b46f2d9e957c94f4f0d Mon Sep 17 00:00:00 2001 From: Kirill Podoprigora Date: Wed, 12 Mar 2025 00:35:16 +0200 Subject: [PATCH 2/2] Make panic's more specific --- compiler/rustc_index/src/slice.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_index/src/slice.rs b/compiler/rustc_index/src/slice.rs index 6e28d1ccf279f..1f19d8c66f02d 100644 --- a/compiler/rustc_index/src/slice.rs +++ b/compiler/rustc_index/src/slice.rs @@ -1,6 +1,7 @@ use std::fmt; use std::marker::PhantomData; use std::ops::{Index, IndexMut}; +use std::slice::GetDisjointMutError::*; use std::slice::{self, SliceIndex}; use crate::{Idx, IndexVec, IntoSliceIdx}; @@ -115,33 +116,35 @@ impl IndexSlice { /// Returns mutable references to two distinct elements, `a` and `b`. /// - /// Panics if `a == b`. + /// Panics if `a == b` or if some of them are out of bounds. #[inline] pub fn pick2_mut(&mut self, a: I, b: I) -> (&mut T, &mut T) { let (ai, bi) = (a.index(), b.index()); - assert!(ai != bi); - let len = self.raw.len(); - assert!(ai < len && bi < len); match self.raw.get_disjoint_mut([ai, bi]) { Ok([a, b]) => (a, b), - Err(_) => panic!("Can't get mutable references"), + Err(OverlappingIndices) => panic!("Indices {ai:?} and {bi:?} are not disjoint!"), + Err(IndexOutOfBounds) => { + panic!("Some indices among ({ai:?}, {bi:?}) are out of bounds") + } } } /// Returns mutable references to three distinct elements. /// - /// Panics if the elements are not distinct. + /// Panics if the elements are not distinct or if some of them are out of bounds. #[inline] pub fn pick3_mut(&mut self, a: I, b: I, c: I) -> (&mut T, &mut T, &mut T) { let (ai, bi, ci) = (a.index(), b.index(), c.index()); - assert!(ai != bi && bi != ci && ci != ai); - let len = self.raw.len(); - assert!(ai < len && bi < len && ci < len); match self.raw.get_disjoint_mut([ai, bi, ci]) { Ok([a, b, c]) => (a, b, c), - Err(_) => panic!("Can't get mutable references"), + Err(OverlappingIndices) => { + panic!("Indices {ai:?}, {bi:?} and {ci:?} are not disjoint!") + } + Err(IndexOutOfBounds) => { + panic!("Some indices among ({ai:?}, {bi:?}, {ci:?}) are out of bounds") + } } }