diff options
| author | bors <bors@rust-lang.org> | 2017-01-03 23:51:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2017-01-03 23:51:42 +0000 |
| commit | 468227129d08b52c4cf90313b29fdad1b80e596b (patch) | |
| tree | 395f940c4de2fd358f5777c4f28b867a4174e2b6 /src/libcore | |
| parent | 8f62c2920077eb5cb81323142fc5dbe6ae8813c0 (diff) | |
| parent | d83fff3b3b9dd0fd6eef862e97f883d171367041 (diff) | |
| download | rust-468227129d08b52c4cf90313b29fdad1b80e596b.tar.gz rust-468227129d08b52c4cf90313b29fdad1b80e596b.zip | |
Auto merge of #38066 - bluss:string-slice-error, r=sfackler
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.
It reports the first error it finds in:
1. begin out of bounds
2. end out of bounds
3. begin <= end violated
3. begin not char boundary
5. end not char boundary.
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αβγ`'
Fixes #38052
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 de418b831cc..db46bd00c8b 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -1746,13 +1746,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")] |
