Skip to content

Commit fa07ba2

Browse files
Auto merge of #150265 - scottmcm:vec-less-ubchecks, r=<try>
Stop emitting UbChecks on every Vec→Slice
2 parents 04813e4 + fd8744f commit fa07ba2

6 files changed

+241
-750
lines changed

library/alloc/src/vec/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,11 @@ impl<T, A: Allocator> Vec<T, A> {
16491649
// * We only construct `&mut` references to `self.buf` through `&mut self` methods; borrow-
16501650
// check ensures that it is not possible to mutably alias `self.buf` within the
16511651
// returned lifetime.
1652-
unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
1652+
unsafe {
1653+
// normally this would use `slice::from_raw_parts`, but it's
1654+
// hot enough that avoiding the UB check is worth it
1655+
&*core::intrinsics::aggregate_raw_ptr::<*const [T], _, _>(self.as_ptr(), self.len)
1656+
}
16531657
}
16541658

16551659
/// Extracts a mutable slice of the entire vector.
@@ -1681,7 +1685,11 @@ impl<T, A: Allocator> Vec<T, A> {
16811685
// * We only construct references to `self.buf` through `&self` and `&mut self` methods;
16821686
// borrow-check ensures that it is not possible to construct a reference to `self.buf`
16831687
// within the returned lifetime.
1684-
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
1688+
unsafe {
1689+
// normally this would use `slice::from_raw_parts_mut`, but it's
1690+
// hot enough that avoiding the UB check is worth it
1691+
&mut *core::intrinsics::aggregate_raw_ptr::<*mut [T], _, _>(self.as_mut_ptr(), self.len)
1692+
}
16851693
}
16861694

16871695
/// Returns a raw pointer to the vector's buffer, or a dangling raw pointer

library/core/src/slice/cmp.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ impl<T, U> const PartialEq<[U]> for [T]
1313
where
1414
T: [const] PartialEq<U>,
1515
{
16+
// It's not worth trying to inline the loops underneath here *in MIR*,
17+
// and preventing it encourages more useful inlining upstream,
18+
// such as in `<str as PartialEq>::eq`.
19+
// The codegen backend can still inline it later if needed.
20+
#[rustc_no_mir_inline]
1621
fn eq(&self, other: &[U]) -> bool {
1722
SlicePartialEq::equal(self, other)
1823
}
19-
20-
fn ne(&self, other: &[U]) -> bool {
21-
SlicePartialEq::not_equal(self, other)
22-
}
2324
}
2425

2526
#[stable(feature = "rust1", since = "1.0.0")]
@@ -99,10 +100,6 @@ impl<T: PartialOrd> PartialOrd for [T] {
99100
#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
100101
const trait SlicePartialEq<B> {
101102
fn equal(&self, other: &[B]) -> bool;
102-
103-
fn not_equal(&self, other: &[B]) -> bool {
104-
!self.equal(other)
105-
}
106103
}
107104

108105
// Generic slice equality

0 commit comments

Comments
 (0)