Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions library/alloctests/tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,14 +612,14 @@ mod slice_index {
data: "abcdef";
good: data[4..4] == "";
bad: data[4..3];
message: "begin > end (4 > 3)";
message: "byte range starts at 4 but ends at 3";
}

in mod rangeinclusive_neg_width {
data: "abcdef";
good: data[4..=3] == "";
bad: data[4..=2];
message: "begin > end (4 > 3)";
message: "byte range starts at 4 but ends at 3";
}
}

Expand Down Expand Up @@ -659,49 +659,49 @@ mod slice_index {
data: super::DATA;
bad: data[super::BAD_START..super::GOOD_END];
message:
"start byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of";
"start byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5 of string)";
}

in mod range_2 {
data: super::DATA;
bad: data[super::GOOD_START..super::BAD_END];
message:
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7 of string)";
}

in mod rangefrom {
data: super::DATA;
bad: data[super::BAD_START..];
message:
"start byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of";
"start byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5 of string)";
}

in mod rangeto {
data: super::DATA;
bad: data[..super::BAD_END];
message:
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7 of string)";
}

in mod rangeinclusive_1 {
data: super::DATA;
bad: data[super::BAD_START..=super::GOOD_END_INCL];
message:
"start byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of";
"start byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5 of string)";
}

in mod rangeinclusive_2 {
data: super::DATA;
bad: data[super::GOOD_START..=super::BAD_END_INCL];
message:
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7 of string)";
}

in mod rangetoinclusive {
data: super::DATA;
bad: data[..=super::BAD_END_INCL];
message:
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of";
"end byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7 of string)";
}
}
}
Expand All @@ -716,18 +716,10 @@ mod slice_index {

// check the panic includes the prefix of the sliced string
#[test]
#[should_panic(
expected = "end byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet"
)]
#[should_panic(expected = "end byte index 1024 is out of bounds for string of length 416")]
fn test_slice_fail_truncated_1() {
let _ = &LOREM_PARAGRAPH[..1024];
}
// check the truncation in the panic message
#[test]
#[should_panic(expected = "luctus, im`[...]")]
fn test_slice_fail_truncated_2() {
let _ = &LOREM_PARAGRAPH[..1024];
}
}

#[test]
Expand Down
7 changes: 7 additions & 0 deletions library/core/src/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ impl fmt::Display for AllocError {
/// A memory block which is [*currently allocated*] may be passed to
/// any method of the allocator that accepts such an argument.
///
/// Additionally, any memory block returned by the allocator must
/// satisfy the allocation invariants described in `core::ptr`.
/// In particular, if a block has base address `p` and size `n`,
/// then `p as usize + n <= usize::MAX` must hold.
///
/// This ensures that pointer arithmetic within the allocation
/// (for example, `ptr.add(len)`) cannot overflow the address space.
/// [*currently allocated*]: #currently-allocated-memory
#[unstable(feature = "allocator_api", issue = "32838")]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
Expand Down
13 changes: 7 additions & 6 deletions library/core/src/panic/unwind_safe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::async_iter::AsyncIterator;
use crate::cell::UnsafeCell;
use crate::fmt;
use crate::future::Future;
use crate::marker::PointeeSized;
use crate::ops::{Deref, DerefMut};
use crate::pin::Pin;
use crate::ptr::{NonNull, Unique};
Expand Down Expand Up @@ -178,17 +179,17 @@ pub struct AssertUnwindSafe<T>(#[stable(feature = "catch_unwind", since = "1.9.0
// * Our custom AssertUnwindSafe wrapper is indeed unwind safe

#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> !UnwindSafe for &mut T {}
impl<T: PointeeSized> !UnwindSafe for &mut T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for &T {}
impl<T: RefUnwindSafe + PointeeSized> UnwindSafe for &T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *const T {}
impl<T: RefUnwindSafe + PointeeSized> UnwindSafe for *const T {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for *mut T {}
impl<T: RefUnwindSafe + PointeeSized> UnwindSafe for *mut T {}
#[unstable(feature = "ptr_internals", issue = "none")]
impl<T: UnwindSafe + ?Sized> UnwindSafe for Unique<T> {}
impl<T: UnwindSafe + PointeeSized> UnwindSafe for Unique<T> {}
#[stable(feature = "nonnull", since = "1.25.0")]
impl<T: RefUnwindSafe + ?Sized> UnwindSafe for NonNull<T> {}
impl<T: RefUnwindSafe + PointeeSized> UnwindSafe for NonNull<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T> UnwindSafe for AssertUnwindSafe<T> {}

Expand Down
16 changes: 6 additions & 10 deletions library/core/src/str/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,21 @@ const fn slice_error_fail_ct(_: &str, _: usize, _: usize) -> ! {

#[track_caller]
fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
const MAX_DISPLAY_LENGTH: usize = 256;
let trunc_len = s.floor_char_boundary(MAX_DISPLAY_LENGTH);
let s_trunc = &s[..trunc_len];
let ellipsis = if trunc_len < s.len() { "[...]" } else { "" };
let len = s.len();

// 1. begin is OOB.
if begin > len {
panic!("start byte index {begin} is out of bounds of `{s_trunc}`{ellipsis}");
panic!("start byte index {begin} is out of bounds for string of length {len}");
}

// 2. end is OOB.
if end > len {
panic!("end byte index {end} is out of bounds of `{s_trunc}`{ellipsis}");
panic!("end byte index {end} is out of bounds for string of length {len}");
}

// 3. range is backwards.
if begin > end {
panic!("begin > end ({begin} > {end}) when slicing `{s_trunc}`{ellipsis}")
panic!("byte range starts at {begin} but ends at {end}");
}

// 4. begin is inside a character.
Expand All @@ -109,7 +105,7 @@ fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
let range = floor..ceil;
let ch = s[floor..ceil].chars().next().unwrap();
panic!(
"start byte index {begin} is not a char boundary; it is inside {ch:?} (bytes {range:?}) of `{s_trunc}`{ellipsis}"
"start byte index {begin} is not a char boundary; it is inside {ch:?} (bytes {range:?} of string)"
)
}

Expand All @@ -120,15 +116,15 @@ fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
let range = floor..ceil;
let ch = s[floor..ceil].chars().next().unwrap();
panic!(
"end byte index {end} is not a char boundary; it is inside {ch:?} (bytes {range:?}) of `{s_trunc}`{ellipsis}"
"end byte index {end} is not a char boundary; it is inside {ch:?} (bytes {range:?} of string)"
)
}

// 6. end is OOB and range is inclusive (end == len).
// This test cannot be combined with 2. above because for cases like
// `"abcαβγ"[4..9]` the error is that 4 is inside 'α', not that 9 is OOB.
debug_assert_eq!(end, len);
panic!("end byte index {end} is out of bounds of `{s_trunc}`{ellipsis}");
panic!("end byte index {end} is out of bounds for string of length {len}");
}

impl str {
Expand Down
17 changes: 14 additions & 3 deletions library/core/src/wtf8.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,11 +484,22 @@ unsafe fn slice_unchecked(s: &Wtf8, begin: usize, end: usize) -> &Wtf8 {
}
}

/// Copied from core::str::raw::slice_error_fail
#[inline(never)]
fn slice_error_fail(s: &Wtf8, begin: usize, end: usize) -> ! {
assert!(begin <= end);
panic!("index {begin} and/or {end} in `{s:?}` do not lie on character boundary");
let len = s.len();
if begin > len {
panic!("start byte index {begin} is out of bounds for string of length {len}");
}
if end > len {
panic!("end byte index {end} is out of bounds for string of length {len}");
}
if begin > end {
panic!("byte range starts at {begin} but ends at {end}");
}
if !s.is_code_point_boundary(begin) {
panic!("byte index {begin} is not a code point boundary");
}
panic!("byte index {end} is not a code point boundary");
}

/// Iterator for the code points of a WTF-8 string.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

thread 'main' ($TID) panicked at $DIR/const-eval-select-backtrace-std.rs:6:8:
start byte index 1 is out of bounds of ``
start byte index 1 is out of bounds for string of length 0
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Loading