diff options
| author | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2016-11-29 04:11:12 +0100 |
|---|---|---|
| committer | Ulrik Sverdrup <bluss@users.noreply.github.com> | 2016-11-30 18:59:58 +0100 |
| commit | d83fff3b3b9dd0fd6eef862e97f883d171367041 (patch) | |
| tree | ab91da72cf2f86842144be21115ad9a3787dd57e /src/libcore | |
| parent | 127a83df6615d09cda6ed9b53f7daba2d78c925d (diff) | |
| download | rust-d83fff3b3b9dd0fd6eef862e97f883d171367041.tar.gz rust-d83fff3b3b9dd0fd6eef862e97f883d171367041.zip | |
Use more specific panic message for &str slicing errors
Separate out of bounds errors from character boundary errors, and print
more details for character boundary errors.
Example:
&"abcαβγ"[..4]
thread 'str::test_slice_fail_boundary_1' panicked at 'byte index 4 is not
a char boundary; it is inside `α` (bytes 3..5) of `abcαβγ`'
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/str/mod.rs | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index b4cd52e59f6..7081c3ebf43 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1741,13 +1741,31 @@ fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) { #[cold] fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! { const MAX_DISPLAY_LENGTH: usize = 256; - let (truncated, s) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH); + let (truncated, s_trunc) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH); let ellipsis = if truncated { "[...]" } else { "" }; + // 1. out of bounds + if begin > s.len() || end > s.len() { + let oob_index = if begin > s.len() { begin } else { end }; + panic!("byte index {} is out of bounds of `{}`{}", oob_index, s_trunc, ellipsis); + } + + // 2. begin <= end assert!(begin <= end, "begin <= end ({} <= {}) when slicing `{}`{}", - begin, end, s, ellipsis); - panic!("index {} and/or {} in `{}`{} do not lie on character boundary", - begin, end, s, ellipsis); + begin, end, s_trunc, ellipsis); + + // 3. character boundary + let index = if !s.is_char_boundary(begin) { begin } else { end }; + // find the character + let mut char_start = index; + while !s.is_char_boundary(char_start) { + char_start -= 1; + } + // `char_start` must be less than len and a char boundary + let ch = s[char_start..].chars().next().unwrap(); + let char_range = char_start .. char_start + ch.len_utf8(); + panic!("byte index {} is not a char boundary; it is inside {:?} (bytes {:?}) of `{}`{}", + index, ch, char_range, s_trunc, ellipsis); } #[stable(feature = "core", since = "1.6.0")] |
