1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 use std::cmp::Ordering::{Equal, Greater, Less};
13 use std::str::from_utf8;
19 assert!("foo" <= "foo");
20 assert!("foo" != "bar");
25 assert_eq!("hello".find('l'), Some(2));
26 assert_eq!("hello".find(|c:char| c == 'o'), Some(4));
27 assert!("hello".find('x').is_none());
28 assert!("hello".find(|c:char| c == 'x').is_none());
29 assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30));
30 assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30));
35 assert_eq!("hello".rfind('l'), Some(3));
36 assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4));
37 assert!("hello".rfind('x').is_none());
38 assert!("hello".rfind(|c:char| c == 'x').is_none());
39 assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30));
40 assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30));
46 let s: String = empty.chars().collect();
48 let data = "ประเทศไทย中";
49 let s: String = data.chars().collect();
54 fn test_into_bytes() {
55 let data = String::from("asdf");
56 let buf = data.into_bytes();
57 assert_eq!(buf, b"asdf");
63 assert_eq!("".find(""), Some(0));
64 assert!("banana".find("apple pie").is_none());
67 assert_eq!(data[0..6].find("ab"), Some(0));
68 assert_eq!(data[2..6].find("ab"), Some(3 - 2));
69 assert!(data[2..4].find("ab").is_none());
71 let string = "ประเทศไทย中华Việt Nam";
72 let mut data = String::from(string);
73 data.push_str(string);
74 assert!(data.find("ไท华").is_none());
75 assert_eq!(data[0..43].find(""), Some(0));
76 assert_eq!(data[6..43].find(""), Some(6 - 6));
78 assert_eq!(data[0..43].find("ประ"), Some( 0));
79 assert_eq!(data[0..43].find("ทศไ"), Some(12));
80 assert_eq!(data[0..43].find("ย中"), Some(24));
81 assert_eq!(data[0..43].find("iệt"), Some(34));
82 assert_eq!(data[0..43].find("Nam"), Some(40));
84 assert_eq!(data[43..86].find("ประ"), Some(43 - 43));
85 assert_eq!(data[43..86].find("ทศไ"), Some(55 - 43));
86 assert_eq!(data[43..86].find("ย中"), Some(67 - 43));
87 assert_eq!(data[43..86].find("iệt"), Some(77 - 43));
88 assert_eq!(data[43..86].find("Nam"), Some(83 - 43));
90 // find every substring -- assert that it finds it, or an earlier occurrence.
91 let string = "Việt Namacbaabcaabaaba";
92 for (i, ci) in string.char_indices() {
93 let ip = i + ci.len_utf8();
94 for j in string[ip..].char_indices()
96 .chain(Some(string.len() - ip))
98 let pat = &string[i..ip + j];
99 assert!(match string.find(pat) {
103 assert!(match string.rfind(pat) {
111 fn s(x: &str) -> String { x.to_string() }
113 macro_rules! test_concat {
114 ($expected: expr, $string: expr) => {
116 let s: String = $string.concat();
117 assert_eq!($expected, s);
123 fn test_concat_for_different_types() {
124 test_concat!("ab", vec![s("a"), s("b")]);
125 test_concat!("ab", vec!["a", "b"]);
129 fn test_concat_for_different_lengths() {
130 let empty: &[&str] = &[];
131 test_concat!("", empty);
132 test_concat!("a", ["a"]);
133 test_concat!("ab", ["a", "b"]);
134 test_concat!("abc", ["", "a", "bc"]);
137 macro_rules! test_join {
138 ($expected: expr, $string: expr, $delim: expr) => {
140 let s = $string.join($delim);
141 assert_eq!($expected, s);
147 fn test_join_for_different_types() {
148 test_join!("a-b", ["a", "b"], "-");
149 let hyphen = "-".to_string();
150 test_join!("a-b", [s("a"), s("b")], &*hyphen);
151 test_join!("a-b", vec!["a", "b"], &*hyphen);
152 test_join!("a-b", &*vec!["a", "b"], "-");
153 test_join!("a-b", vec![s("a"), s("b")], "-");
157 fn test_join_for_different_lengths() {
158 let empty: &[&str] = &[];
159 test_join!("", empty, "-");
160 test_join!("a", ["a"], "-");
161 test_join!("a-b", ["a", "b"], "-");
162 test_join!("-a-bc", ["", "a", "bc"], "-");
166 fn test_unsafe_slice() {
167 assert_eq!("ab", unsafe {"abc".slice_unchecked(0, 2)});
168 assert_eq!("bc", unsafe {"abc".slice_unchecked(1, 3)});
169 assert_eq!("", unsafe {"abc".slice_unchecked(1, 1)});
170 fn a_million_letter_a() -> String {
172 let mut rs = String::new();
174 rs.push_str("aaaaaaaaaa");
179 fn half_a_million_letter_a() -> String {
181 let mut rs = String::new();
183 rs.push_str("aaaaa");
188 let letters = a_million_letter_a();
189 assert_eq!(half_a_million_letter_a(),
190 unsafe { letters.slice_unchecked(0, 500000)});
194 fn test_starts_with() {
195 assert!("".starts_with(""));
196 assert!("abc".starts_with(""));
197 assert!("abc".starts_with("a"));
198 assert!(!"a".starts_with("abc"));
199 assert!(!"".starts_with("abc"));
200 assert!(!"ödd".starts_with("-"));
201 assert!("ödd".starts_with("öd"));
205 fn test_ends_with() {
206 assert!("".ends_with(""));
207 assert!("abc".ends_with(""));
208 assert!("abc".ends_with("c"));
209 assert!(!"a".ends_with("abc"));
210 assert!(!"".ends_with("abc"));
211 assert!(!"ddö".ends_with("-"));
212 assert!("ddö".ends_with("dö"));
217 assert!("".is_empty());
218 assert!(!"a".is_empty());
223 assert_eq!("".replacen('a', "b", 5), "");
224 assert_eq!("acaaa".replacen("a", "b", 3), "bcbba");
225 assert_eq!("aaaa".replacen("a", "b", 0), "aaaa");
228 assert_eq!(" test test ".replacen(test, "toast", 3), " toast toast ");
229 assert_eq!(" test test ".replacen(test, "toast", 0), " test test ");
230 assert_eq!(" test test ".replacen(test, "", 5), " ");
232 assert_eq!("qwer123zxc789".replacen(char::is_numeric, "", 3), "qwerzxc789");
238 assert_eq!("".replace(a, "b"), "");
239 assert_eq!("a".replace(a, "b"), "b");
240 assert_eq!("ab".replace(a, "b"), "bb");
242 assert_eq!(" test test ".replace(test, "toast"), " toast toast ");
243 assert_eq!(" test test ".replace(test, ""), " ");
247 fn test_replace_2a() {
248 let data = "ประเทศไทย中华";
249 let repl = "دولة الكويت";
252 let a2 = "دولة الكويتทศไทย中华";
253 assert_eq!(data.replace(a, repl), a2);
257 fn test_replace_2b() {
258 let data = "ประเทศไทย中华";
259 let repl = "دولة الكويت";
262 let b2 = "ปรدولة الكويتทศไทย中华";
263 assert_eq!(data.replace(b, repl), b2);
267 fn test_replace_2c() {
268 let data = "ประเทศไทย中华";
269 let repl = "دولة الكويت";
272 let c2 = "ประเทศไทยدولة الكويت";
273 assert_eq!(data.replace(c, repl), c2);
277 fn test_replace_2d() {
278 let data = "ประเทศไทย中华";
279 let repl = "دولة الكويت";
282 assert_eq!(data.replace(d, repl), data);
286 fn test_replace_pattern() {
287 let data = "abcdαβγδabcdαβγδ";
288 assert_eq!(data.replace("dαβ", "😺😺😺"), "abc😺😺😺γδabc😺😺😺γδ");
289 assert_eq!(data.replace('γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
290 assert_eq!(data.replace(&['a', 'γ'] as &[_], "😺😺😺"), "😺😺😺bcdαβ😺😺😺δ😺😺😺bcdαβ😺😺😺δ");
291 assert_eq!(data.replace(|c| c == 'γ', "😺😺😺"), "abcdαβ😺😺😺δabcdαβ😺😺😺δ");
296 assert_eq!("ab", &"abc"[0..2]);
297 assert_eq!("bc", &"abc"[1..3]);
298 assert_eq!("", &"abc"[1..1]);
299 assert_eq!("\u{65e5}", &"\u{65e5}\u{672c}"[0..3]);
301 let data = "ประเทศไทย中华";
302 assert_eq!("ป", &data[0..3]);
303 assert_eq!("ร", &data[3..6]);
304 assert_eq!("", &data[3..3]);
305 assert_eq!("华", &data[30..33]);
307 fn a_million_letter_x() -> String {
309 let mut rs = String::new();
311 rs.push_str("华华华华华华华华华华");
316 fn half_a_million_letter_x() -> String {
318 let mut rs = String::new();
320 rs.push_str("华华华华华");
325 let letters = a_million_letter_x();
326 assert_eq!(half_a_million_letter_x(), &letters[0..3 * 500000]);
331 let ss = "中华Việt Nam";
333 assert_eq!("华", &ss[3..6]);
334 assert_eq!("Việt Nam", &ss[6..16]);
336 assert_eq!("ab", &"abc"[0..2]);
337 assert_eq!("bc", &"abc"[1..3]);
338 assert_eq!("", &"abc"[1..1]);
340 assert_eq!("中", &ss[0..3]);
341 assert_eq!("华V", &ss[3..7]);
342 assert_eq!("", &ss[3..3]);
357 fn test_slice_fail() {
363 fn test_is_char_boundary() {
364 let s = "ศไทย中华Việt Nam β-release 🐱123";
365 assert!(s.is_char_boundary(0));
366 assert!(s.is_char_boundary(s.len()));
367 assert!(!s.is_char_boundary(s.len() + 1));
368 for (i, ch) in s.char_indices() {
369 // ensure character locations are boundaries and continuation bytes are not
370 assert!(s.is_char_boundary(i), "{} is a char boundary in {:?}", i, s);
371 for j in 1..ch.len_utf8() {
372 assert!(!s.is_char_boundary(i + j),
373 "{} should not be a char boundary in {:?}", i + j, s);
377 const LOREM_PARAGRAPH: &'static str = "\
378 Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
379 ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
380 eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
381 sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
382 tempus vel, gravida nec quam.";
384 // check the panic includes the prefix of the sliced string
386 #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")]
387 fn test_slice_fail_truncated_1() {
388 &LOREM_PARAGRAPH[..1024];
390 // check the truncation in the panic message
392 #[should_panic(expected="luctus, im`[...]")]
393 fn test_slice_fail_truncated_2() {
394 &LOREM_PARAGRAPH[..1024];
398 #[should_panic(expected="byte index 4 is not a char boundary; it is inside 'α' (bytes 3..5) of")]
399 fn test_slice_fail_boundary_1() {
404 #[should_panic(expected="byte index 6 is not a char boundary; it is inside 'β' (bytes 5..7) of")]
405 fn test_slice_fail_boundary_2() {
410 fn test_slice_from() {
411 assert_eq!(&"abcd"[0..], "abcd");
412 assert_eq!(&"abcd"[2..], "cd");
413 assert_eq!(&"abcd"[4..], "");
417 assert_eq!(&"abcd"[..0], "");
418 assert_eq!(&"abcd"[..2], "ab");
419 assert_eq!(&"abcd"[..4], "abcd");
423 fn test_trim_left_matches() {
424 let v: &[char] = &[];
425 assert_eq!(" *** foo *** ".trim_left_matches(v), " *** foo *** ");
426 let chars: &[char] = &['*', ' '];
427 assert_eq!(" *** foo *** ".trim_left_matches(chars), "foo *** ");
428 assert_eq!(" *** *** ".trim_left_matches(chars), "");
429 assert_eq!("foo *** ".trim_left_matches(chars), "foo *** ");
431 assert_eq!("11foo1bar11".trim_left_matches('1'), "foo1bar11");
432 let chars: &[char] = &['1', '2'];
433 assert_eq!("12foo1bar12".trim_left_matches(chars), "foo1bar12");
434 assert_eq!("123foo1bar123".trim_left_matches(|c: char| c.is_numeric()), "foo1bar123");
438 fn test_trim_right_matches() {
439 let v: &[char] = &[];
440 assert_eq!(" *** foo *** ".trim_right_matches(v), " *** foo *** ");
441 let chars: &[char] = &['*', ' '];
442 assert_eq!(" *** foo *** ".trim_right_matches(chars), " *** foo");
443 assert_eq!(" *** *** ".trim_right_matches(chars), "");
444 assert_eq!(" *** foo".trim_right_matches(chars), " *** foo");
446 assert_eq!("11foo1bar11".trim_right_matches('1'), "11foo1bar");
447 let chars: &[char] = &['1', '2'];
448 assert_eq!("12foo1bar12".trim_right_matches(chars), "12foo1bar");
449 assert_eq!("123foo1bar123".trim_right_matches(|c: char| c.is_numeric()), "123foo1bar");
453 fn test_trim_matches() {
454 let v: &[char] = &[];
455 assert_eq!(" *** foo *** ".trim_matches(v), " *** foo *** ");
456 let chars: &[char] = &['*', ' '];
457 assert_eq!(" *** foo *** ".trim_matches(chars), "foo");
458 assert_eq!(" *** *** ".trim_matches(chars), "");
459 assert_eq!("foo".trim_matches(chars), "foo");
461 assert_eq!("11foo1bar11".trim_matches('1'), "foo1bar");
462 let chars: &[char] = &['1', '2'];
463 assert_eq!("12foo1bar12".trim_matches(chars), "foo1bar");
464 assert_eq!("123foo1bar123".trim_matches(|c: char| c.is_numeric()), "foo1bar");
468 fn test_trim_left() {
469 assert_eq!("".trim_left(), "");
470 assert_eq!("a".trim_left(), "a");
471 assert_eq!(" ".trim_left(), "");
472 assert_eq!(" blah".trim_left(), "blah");
473 assert_eq!(" \u{3000} wut".trim_left(), "wut");
474 assert_eq!("hey ".trim_left(), "hey ");
478 fn test_trim_right() {
479 assert_eq!("".trim_right(), "");
480 assert_eq!("a".trim_right(), "a");
481 assert_eq!(" ".trim_right(), "");
482 assert_eq!("blah ".trim_right(), "blah");
483 assert_eq!("wut \u{3000} ".trim_right(), "wut");
484 assert_eq!(" hey".trim_right(), " hey");
489 assert_eq!("".trim(), "");
490 assert_eq!("a".trim(), "a");
491 assert_eq!(" ".trim(), "");
492 assert_eq!(" blah ".trim(), "blah");
493 assert_eq!("\nwut \u{3000} ".trim(), "wut");
494 assert_eq!(" hey dude ".trim(), "hey dude");
498 fn test_is_whitespace() {
499 assert!("".chars().all(|c| c.is_whitespace()));
500 assert!(" ".chars().all(|c| c.is_whitespace()));
501 assert!("\u{2009}".chars().all(|c| c.is_whitespace())); // Thin space
502 assert!(" \n\t ".chars().all(|c| c.is_whitespace()));
503 assert!(!" _ ".chars().all(|c| c.is_whitespace()));
508 // deny overlong encodings
509 assert!(from_utf8(&[0xc0, 0x80]).is_err());
510 assert!(from_utf8(&[0xc0, 0xae]).is_err());
511 assert!(from_utf8(&[0xe0, 0x80, 0x80]).is_err());
512 assert!(from_utf8(&[0xe0, 0x80, 0xaf]).is_err());
513 assert!(from_utf8(&[0xe0, 0x81, 0x81]).is_err());
514 assert!(from_utf8(&[0xf0, 0x82, 0x82, 0xac]).is_err());
515 assert!(from_utf8(&[0xf4, 0x90, 0x80, 0x80]).is_err());
518 assert!(from_utf8(&[0xED, 0xA0, 0x80]).is_err());
519 assert!(from_utf8(&[0xED, 0xBF, 0xBF]).is_err());
521 assert!(from_utf8(&[0xC2, 0x80]).is_ok());
522 assert!(from_utf8(&[0xDF, 0xBF]).is_ok());
523 assert!(from_utf8(&[0xE0, 0xA0, 0x80]).is_ok());
524 assert!(from_utf8(&[0xED, 0x9F, 0xBF]).is_ok());
525 assert!(from_utf8(&[0xEE, 0x80, 0x80]).is_ok());
526 assert!(from_utf8(&[0xEF, 0xBF, 0xBF]).is_ok());
527 assert!(from_utf8(&[0xF0, 0x90, 0x80, 0x80]).is_ok());
528 assert!(from_utf8(&[0xF4, 0x8F, 0xBF, 0xBF]).is_ok());
532 fn from_utf8_mostly_ascii() {
533 // deny invalid bytes embedded in long stretches of ascii
535 let mut data = [0; 128];
537 assert!(from_utf8(&data).is_err());
539 assert!(from_utf8(&data).is_err());
544 fn from_utf8_error() {
546 ($input: expr, $expected_valid_up_to: expr, $expected_error_len: expr) => {
547 let error = from_utf8($input).unwrap_err();
548 assert_eq!(error.valid_up_to(), $expected_valid_up_to);
549 assert_eq!(error.error_len(), $expected_error_len);
552 test!(b"A\xC3\xA9 \xFF ", 4, Some(1));
553 test!(b"A\xC3\xA9 \x80 ", 4, Some(1));
554 test!(b"A\xC3\xA9 \xC1 ", 4, Some(1));
555 test!(b"A\xC3\xA9 \xC1", 4, Some(1));
556 test!(b"A\xC3\xA9 \xC2", 4, None);
557 test!(b"A\xC3\xA9 \xC2 ", 4, Some(1));
558 test!(b"A\xC3\xA9 \xC2\xC0", 4, Some(1));
559 test!(b"A\xC3\xA9 \xE0", 4, None);
560 test!(b"A\xC3\xA9 \xE0\x9F", 4, Some(1));
561 test!(b"A\xC3\xA9 \xE0\xA0", 4, None);
562 test!(b"A\xC3\xA9 \xE0\xA0\xC0", 4, Some(2));
563 test!(b"A\xC3\xA9 \xE0\xA0 ", 4, Some(2));
564 test!(b"A\xC3\xA9 \xED\xA0\x80 ", 4, Some(1));
565 test!(b"A\xC3\xA9 \xF1", 4, None);
566 test!(b"A\xC3\xA9 \xF1\x80", 4, None);
567 test!(b"A\xC3\xA9 \xF1\x80\x80", 4, None);
568 test!(b"A\xC3\xA9 \xF1 ", 4, Some(1));
569 test!(b"A\xC3\xA9 \xF1\x80 ", 4, Some(2));
570 test!(b"A\xC3\xA9 \xF1\x80\x80 ", 4, Some(3));
577 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
578 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
582 assert_eq!("".as_bytes(), b);
583 assert_eq!("abc".as_bytes(), b"abc");
584 assert_eq!("ศไทย中华Việt Nam".as_bytes(), v);
589 fn test_as_bytes_fail() {
590 // Don't double free. (I'm not sure if this exercises the
591 // original problem code path anymore.)
592 let s = String::from("");
593 let _bytes = s.as_bytes();
599 let buf = "hello".as_ptr();
601 assert_eq!(*buf.offset(0), b'h');
602 assert_eq!(*buf.offset(1), b'e');
603 assert_eq!(*buf.offset(2), b'l');
604 assert_eq!(*buf.offset(3), b'l');
605 assert_eq!(*buf.offset(4), b'o');
610 fn vec_str_conversions() {
611 let s1: String = String::from("All mimsy were the borogoves");
613 let v: Vec<u8> = s1.as_bytes().to_vec();
614 let s2: String = String::from(from_utf8(&v).unwrap());
620 let a: u8 = s1.as_bytes()[i];
621 let b: u8 = s2.as_bytes()[i];
629 assert!("abcde".contains("bcd"));
630 assert!("abcde".contains("abcd"));
631 assert!("abcde".contains("bcde"));
632 assert!("abcde".contains(""));
633 assert!("".contains(""));
634 assert!(!"abcde".contains("def"));
635 assert!(!"".contains("a"));
637 let data = "ประเทศไทย中华Việt Nam";
638 assert!(data.contains("ประเ"));
639 assert!(data.contains("ะเ"));
640 assert!(data.contains("中华"));
641 assert!(!data.contains("ไท华"));
645 fn test_contains_char() {
646 assert!("abc".contains('b'));
647 assert!("a".contains('a'));
648 assert!(!"abc".contains('d'));
649 assert!(!"".contains('a'));
654 let s = "ศไทย中华Việt Nam";
655 for (index, _) in s.char_indices() {
656 let (a, b) = s.split_at(index);
657 assert_eq!(&s[..a.len()], a);
658 assert_eq!(&s[a.len()..], b);
660 let (a, b) = s.split_at(s.len());
666 fn test_split_at_mut() {
667 use std::ascii::AsciiExt;
668 let mut s = "Hello World".to_string();
670 let (a, b) = s.split_at_mut(5);
671 a.make_ascii_uppercase();
672 b.make_ascii_lowercase();
674 assert_eq!(s, "HELLO world");
679 fn test_split_at_boundscheck() {
680 let s = "ศไทย中华Việt Nam";
685 fn test_escape_unicode() {
686 assert_eq!("abc".escape_unicode(), "\\u{61}\\u{62}\\u{63}");
687 assert_eq!("a c".escape_unicode(), "\\u{61}\\u{20}\\u{63}");
688 assert_eq!("\r\n\t".escape_unicode(), "\\u{d}\\u{a}\\u{9}");
689 assert_eq!("'\"\\".escape_unicode(), "\\u{27}\\u{22}\\u{5c}");
690 assert_eq!("\x00\x01\u{fe}\u{ff}".escape_unicode(), "\\u{0}\\u{1}\\u{fe}\\u{ff}");
691 assert_eq!("\u{100}\u{ffff}".escape_unicode(), "\\u{100}\\u{ffff}");
692 assert_eq!("\u{10000}\u{10ffff}".escape_unicode(), "\\u{10000}\\u{10ffff}");
693 assert_eq!("ab\u{fb00}".escape_unicode(), "\\u{61}\\u{62}\\u{fb00}");
694 assert_eq!("\u{1d4ea}\r".escape_unicode(), "\\u{1d4ea}\\u{d}");
698 fn test_escape_debug() {
699 assert_eq!("abc".escape_debug(), "abc");
700 assert_eq!("a c".escape_debug(), "a c");
701 assert_eq!("éèê".escape_debug(), "éèê");
702 assert_eq!("\r\n\t".escape_debug(), "\\r\\n\\t");
703 assert_eq!("'\"\\".escape_debug(), "\\'\\\"\\\\");
704 assert_eq!("\u{7f}\u{ff}".escape_debug(), "\\u{7f}\u{ff}");
705 assert_eq!("\u{100}\u{ffff}".escape_debug(), "\u{100}\\u{ffff}");
706 assert_eq!("\u{10000}\u{10ffff}".escape_debug(), "\u{10000}\\u{10ffff}");
707 assert_eq!("ab\u{200b}".escape_debug(), "ab\\u{200b}");
708 assert_eq!("\u{10d4ea}\r".escape_debug(), "\\u{10d4ea}\\r");
712 fn test_escape_default() {
713 assert_eq!("abc".escape_default(), "abc");
714 assert_eq!("a c".escape_default(), "a c");
715 assert_eq!("éèê".escape_default(), "\\u{e9}\\u{e8}\\u{ea}");
716 assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t");
717 assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\");
718 assert_eq!("\u{7f}\u{ff}".escape_default(), "\\u{7f}\\u{ff}");
719 assert_eq!("\u{100}\u{ffff}".escape_default(), "\\u{100}\\u{ffff}");
720 assert_eq!("\u{10000}\u{10ffff}".escape_default(), "\\u{10000}\\u{10ffff}");
721 assert_eq!("ab\u{200b}".escape_default(), "ab\\u{200b}");
722 assert_eq!("\u{10d4ea}\r".escape_default(), "\\u{10d4ea}\\r");
726 fn test_total_ord() {
727 assert_eq!("1234".cmp("123"), Greater);
728 assert_eq!("123".cmp("1234"), Less);
729 assert_eq!("1234".cmp("1234"), Equal);
730 assert_eq!("12345555".cmp("123456"), Less);
731 assert_eq!("22".cmp("1234"), Greater);
736 let s = "ศไทย中华Việt Nam";
737 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
743 assert_eq!(c, v[pos]);
746 assert_eq!(pos, v.len());
747 assert_eq!(s.chars().count(), v.len());
751 fn test_rev_iterator() {
752 let s = "ศไทย中华Việt Nam";
753 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
756 let it = s.chars().rev();
759 assert_eq!(c, v[pos]);
762 assert_eq!(pos, v.len());
766 fn test_chars_decoding() {
767 let mut bytes = [0; 4];
768 for c in (0..0x110000).filter_map(::std::char::from_u32) {
769 let s = c.encode_utf8(&mut bytes);
770 if Some(c) != s.chars().next() {
771 panic!("character {:x}={} does not decode correctly", c as u32, c);
777 fn test_chars_rev_decoding() {
778 let mut bytes = [0; 4];
779 for c in (0..0x110000).filter_map(::std::char::from_u32) {
780 let s = c.encode_utf8(&mut bytes);
781 if Some(c) != s.chars().rev().next() {
782 panic!("character {:x}={} does not decode correctly", c as u32, c);
788 fn test_iterator_clone() {
789 let s = "ศไทย中华Việt Nam";
790 let mut it = s.chars();
792 assert!(it.clone().zip(it).all(|(x,y)| x == y));
796 fn test_iterator_last() {
797 let s = "ศไทย中华Việt Nam";
798 let mut it = s.chars();
800 assert_eq!(it.last(), Some('m'));
804 fn test_bytesator() {
805 let s = "ศไทย中华Việt Nam";
807 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
808 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
814 assert_eq!(b, v[pos]);
820 fn test_bytes_revator() {
821 let s = "ศไทย中华Việt Nam";
823 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
824 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
827 let mut pos = v.len();
829 for b in s.bytes().rev() {
831 assert_eq!(b, v[pos]);
836 fn test_bytesator_nth() {
837 let s = "ศไทย中华Việt Nam";
839 224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
840 184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
844 let mut b = s.bytes();
845 assert_eq!(b.nth(2).unwrap(), v[2]);
846 assert_eq!(b.nth(10).unwrap(), v[10]);
847 assert_eq!(b.nth(200), None);
851 fn test_bytesator_count() {
852 let s = "ศไทย中华Việt Nam";
855 assert_eq!(b.count(), 28)
859 fn test_bytesator_last() {
860 let s = "ศไทย中华Việt Nam";
863 assert_eq!(b.last().unwrap(), 109)
867 fn test_char_indicesator() {
868 let s = "ศไทย中华Việt Nam";
869 let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
870 let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
873 let it = s.char_indices();
876 assert_eq!(c, (p[pos], v[pos]));
879 assert_eq!(pos, v.len());
880 assert_eq!(pos, p.len());
884 fn test_char_indices_revator() {
885 let s = "ศไทย中华Việt Nam";
886 let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
887 let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
890 let it = s.char_indices().rev();
893 assert_eq!(c, (p[pos], v[pos]));
896 assert_eq!(pos, v.len());
897 assert_eq!(pos, p.len());
901 fn test_char_indices_last() {
902 let s = "ศไทย中华Việt Nam";
903 let mut it = s.char_indices();
905 assert_eq!(it.last(), Some((27, 'm')));
909 fn test_splitn_char_iterator() {
910 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
912 let split: Vec<&str> = data.splitn(4, ' ').collect();
913 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
915 let split: Vec<&str> = data.splitn(4, |c: char| c == ' ').collect();
916 assert_eq!(split, ["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
919 let split: Vec<&str> = data.splitn(4, 'ä').collect();
920 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
922 let split: Vec<&str> = data.splitn(4, |c: char| c == 'ä').collect();
923 assert_eq!(split, ["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
927 fn test_split_char_iterator_no_trailing() {
928 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
930 let split: Vec<&str> = data.split('\n').collect();
931 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
933 let split: Vec<&str> = data.split_terminator('\n').collect();
934 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
939 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
941 let split: Vec<&str> = data.rsplit(' ').collect();
942 assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
944 let split: Vec<&str> = data.rsplit("lämb").collect();
945 assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
947 let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
948 assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
953 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
955 let split: Vec<&str> = data.rsplitn(2, ' ').collect();
956 assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
958 let split: Vec<&str> = data.rsplitn(2, "lämb").collect();
959 assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
961 let split: Vec<&str> = data.rsplitn(2, |c: char| c == 'ä').collect();
962 assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
966 fn test_split_whitespace() {
967 let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";
968 let words: Vec<&str> = data.split_whitespace().collect();
969 assert_eq!(words, ["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
974 let data = "\nMäry häd ä little lämb\n\r\nLittle lämb\n";
975 let lines: Vec<&str> = data.lines().collect();
976 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
978 let data = "\r\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
979 let lines: Vec<&str> = data.lines().collect();
980 assert_eq!(lines, ["", "Märy häd ä little lämb", "", "Little lämb"]);
984 fn test_splitator() {
985 fn t(s: &str, sep: &str, u: &[&str]) {
986 let v: Vec<&str> = s.split(sep).collect();
989 t("--1233345--", "12345", &["--1233345--"]);
990 t("abc::hello::there", "::", &["abc", "hello", "there"]);
991 t("::hello::there", "::", &["", "hello", "there"]);
992 t("hello::there::", "::", &["hello", "there", ""]);
993 t("::hello::there::", "::", &["", "hello", "there", ""]);
994 t("ประเทศไทย中华Việt Nam", "中华", &["ประเทศไทย", "Việt Nam"]);
995 t("zzXXXzzYYYzz", "zz", &["", "XXX", "YYY", ""]);
996 t("zzXXXzYYYz", "XXX", &["zz", "zYYYz"]);
997 t(".XXX.YYY.", ".", &["", "XXX", "YYY", ""]);
999 t("zz", "zz", &["",""]);
1000 t("ok", "z", &["ok"]);
1001 t("zzz", "zz", &["","z"]);
1002 t("zzzzz", "zz", &["","","z"]);
1006 fn test_str_default() {
1007 use std::default::Default;
1009 fn t<S: Default + AsRef<str>>() {
1010 let s: S = Default::default();
1011 assert_eq!(s.as_ref(), "");
1019 fn test_str_container() {
1020 fn sum_len(v: &[&str]) -> usize {
1021 v.iter().map(|x| x.len()).sum()
1025 assert_eq!(5, sum_len(&["012", "", "34"]));
1026 assert_eq!(5, sum_len(&["01", "2", "34", ""]));
1027 assert_eq!(5, sum_len(&[s]));
1031 fn test_str_from_utf8() {
1033 assert_eq!(from_utf8(xs), Ok("hello"));
1035 let xs = "ศไทย中华Việt Nam".as_bytes();
1036 assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
1038 let xs = b"hello\xFF";
1039 assert!(from_utf8(xs).is_err());
1043 fn test_pattern_deref_forward() {
1044 let data = "aabcdaa";
1045 assert!(data.contains("bcd"));
1046 assert!(data.contains(&"bcd"));
1047 assert!(data.contains(&"bcd".to_string()));
1051 fn test_empty_match_indices() {
1053 let vec: Vec<_> = data.match_indices("").collect();
1054 assert_eq!(vec, [(0, ""), (1, ""), (3, ""), (6, ""), (7, "")]);
1058 fn test_bool_from_str() {
1059 assert_eq!("true".parse().ok(), Some(true));
1060 assert_eq!("false".parse().ok(), Some(false));
1061 assert_eq!("not even a boolean".parse::<bool>().ok(), None);
1064 fn check_contains_all_substrings(s: &str) {
1065 assert!(s.contains(""));
1066 for i in 0..s.len() {
1067 for j in i+1..s.len() + 1 {
1068 assert!(s.contains(&s[i..j]));
1074 fn strslice_issue_16589() {
1075 assert!("bananas".contains("nana"));
1077 // prior to the fix for #16589, x.contains("abcdabcd") returned false
1078 // test all substrings for good measure
1079 check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
1083 fn strslice_issue_16878() {
1084 assert!(!"1234567ah012345678901ah".contains("hah"));
1085 assert!(!"00abc01234567890123456789abc".contains("bcabc"));
1090 fn test_strslice_contains() {
1091 let x = "There are moments, Jeeves, when one asks oneself, 'Do trousers matter?'";
1092 check_contains_all_substrings(x);
1096 fn test_rsplitn_char_iterator() {
1097 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1099 let mut split: Vec<&str> = data.rsplitn(4, ' ').collect();
1101 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1103 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == ' ').collect();
1105 assert_eq!(split, ["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
1108 let mut split: Vec<&str> = data.rsplitn(4, 'ä').collect();
1110 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1112 let mut split: Vec<&str> = data.rsplitn(4, |c: char| c == 'ä').collect();
1114 assert_eq!(split, ["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
1118 fn test_split_char_iterator() {
1119 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1121 let split: Vec<&str> = data.split(' ').collect();
1122 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1124 let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
1126 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1128 let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
1129 assert_eq!( split, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1131 let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
1133 assert_eq!(rsplit, ["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
1136 let split: Vec<&str> = data.split('ä').collect();
1137 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1139 let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
1141 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1143 let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
1144 assert_eq!( split, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1146 let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
1148 assert_eq!(rsplit, ["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
1152 fn test_rev_split_char_iterator_no_trailing() {
1153 let data = "\nMäry häd ä little lämb\nLittle lämb\n";
1155 let mut split: Vec<&str> = data.split('\n').rev().collect();
1157 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb", ""]);
1159 let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
1161 assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
1165 fn test_utf16_code_units() {
1166 use std_unicode::str::Utf16Encoder;
1167 assert_eq!(Utf16Encoder::new(vec!['é', '\u{1F4A9}'].into_iter()).collect::<Vec<u16>>(),
1168 [0xE9, 0xD83D, 0xDCA9])
1172 fn starts_with_in_unicode() {
1173 assert!(!"├── Cargo.toml".starts_with("# "));
1177 fn starts_short_long() {
1178 assert!(!"".starts_with("##"));
1179 assert!(!"##".starts_with("####"));
1180 assert!("####".starts_with("##"));
1181 assert!(!"##ä".starts_with("####"));
1182 assert!("####ä".starts_with("##"));
1183 assert!(!"##".starts_with("####ä"));
1184 assert!("##ä##".starts_with("##ä"));
1186 assert!("".starts_with(""));
1187 assert!("ä".starts_with(""));
1188 assert!("#ä".starts_with(""));
1189 assert!("##ä".starts_with(""));
1190 assert!("ä###".starts_with(""));
1191 assert!("#ä##".starts_with(""));
1192 assert!("##ä#".starts_with(""));
1196 fn contains_weird_cases() {
1197 assert!("* \t".contains(' '));
1198 assert!(!"* \t".contains('?'));
1199 assert!(!"* \t".contains('\u{1F4A9}'));
1204 assert_eq!(" \t a \t ".trim_left_matches(|c: char| c.is_whitespace()),
1206 assert_eq!(" \t a \t ".trim_right_matches(|c: char| c.is_whitespace()),
1208 assert_eq!(" \t a \t ".trim_matches(|c: char| c.is_whitespace()),
1210 assert_eq!(" \t \t ".trim_left_matches(|c: char| c.is_whitespace()),
1212 assert_eq!(" \t \t ".trim_right_matches(|c: char| c.is_whitespace()),
1214 assert_eq!(" \t \t ".trim_matches(|c: char| c.is_whitespace()),
1220 assert_eq!("".to_lowercase(), "");
1221 assert_eq!("AÉDžaé ".to_lowercase(), "aédžaé ");
1223 // https://github.com/rust-lang/rust/issues/26035
1224 assert_eq!("ΑΣ".to_lowercase(), "ας");
1225 assert_eq!("Α'Σ".to_lowercase(), "α'ς");
1226 assert_eq!("Α''Σ".to_lowercase(), "α''ς");
1228 assert_eq!("ΑΣ Α".to_lowercase(), "ας α");
1229 assert_eq!("Α'Σ Α".to_lowercase(), "α'ς α");
1230 assert_eq!("Α''Σ Α".to_lowercase(), "α''ς α");
1232 assert_eq!("ΑΣ' Α".to_lowercase(), "ας' α");
1233 assert_eq!("ΑΣ'' Α".to_lowercase(), "ας'' α");
1235 assert_eq!("Α'Σ' Α".to_lowercase(), "α'ς' α");
1236 assert_eq!("Α''Σ'' Α".to_lowercase(), "α''ς'' α");
1238 assert_eq!("Α Σ".to_lowercase(), "α σ");
1239 assert_eq!("Α 'Σ".to_lowercase(), "α 'σ");
1240 assert_eq!("Α ''Σ".to_lowercase(), "α ''σ");
1242 assert_eq!("Σ".to_lowercase(), "σ");
1243 assert_eq!("'Σ".to_lowercase(), "'σ");
1244 assert_eq!("''Σ".to_lowercase(), "''σ");
1246 assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
1247 assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
1248 assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
1253 assert_eq!("".to_uppercase(), "");
1254 assert_eq!("aéDžßfiᾀ".to_uppercase(), "AÉDŽSSFIἈΙ");
1258 fn test_into_string() {
1259 // The only way to acquire a Box<str> in the first place is through a String, so just
1260 // test that we can round-trip between Box<str> and String.
1261 let string = String::from("Some text goes here");
1262 assert_eq!(string.clone().into_boxed_str().into_string(), string);
1266 fn test_box_slice_clone() {
1267 let data = String::from("hello HELLO hello HELLO yes YES 5 中ä华!!!");
1268 let data2 = data.clone().into_boxed_str().clone().into_string();
1270 assert_eq!(data, data2);
1274 fn test_cow_from() {
1275 let borrowed = "borrowed";
1276 let owned = String::from("owned");
1277 match (Cow::from(owned.clone()), Cow::from(borrowed)) {
1278 (Cow::Owned(o), Cow::Borrowed(b)) => assert!(o == owned && b == borrowed),
1279 _ => panic!("invalid `Cow::from`"),
1285 assert_eq!("".repeat(3), "");
1286 assert_eq!("abc".repeat(0), "");
1287 assert_eq!("α".repeat(3), "ααα");
1291 use std::str::pattern::Pattern;
1292 use std::str::pattern::{Searcher, ReverseSearcher};
1293 use std::str::pattern::SearchStep::{self, Match, Reject, Done};
1295 macro_rules! make_test {
1296 ($name:ident, $p:expr, $h:expr, [$($e:expr,)*]) => {
1297 #[allow(unused_imports)]
1299 use std::str::pattern::SearchStep::{Match, Reject};
1300 use super::{cmp_search_to_vec};
1303 cmp_search_to_vec(false, $p, $h, vec![$($e),*]);
1307 cmp_search_to_vec(true, $p, $h, vec![$($e),*]);
1313 fn cmp_search_to_vec<'a, P: Pattern<'a>>(rev: bool, pat: P, haystack: &'a str,
1314 right: Vec<SearchStep>)
1315 where P::Searcher: ReverseSearcher<'a>
1317 let mut searcher = pat.into_searcher(haystack);
1320 match if !rev {searcher.next()} else {searcher.next_back()} {
1321 Match(a, b) => v.push(Match(a, b)),
1322 Reject(a, b) => v.push(Reject(a, b)),
1330 let mut first_index = 0;
1333 for (i, e) in right.iter().enumerate() {
1335 Match(a, b) | Reject(a, b)
1336 if a <= b && a == first_index => {
1346 if let Some(err) = err {
1347 panic!("Input skipped range at {}", err);
1350 if first_index != haystack.len() {
1351 panic!("Did not cover whole input");
1354 assert_eq!(v, right);
1357 make_test!(str_searcher_ascii_haystack, "bb", "abbcbbd", [
1364 make_test!(str_searcher_ascii_haystack_seq, "bb", "abbcbbbbd", [
1372 make_test!(str_searcher_empty_needle_ascii_haystack, "", "abbcbbd", [
1389 make_test!(str_searcher_mulibyte_haystack, " ", "├──", [
1394 make_test!(str_searcher_empty_needle_mulibyte_haystack, "", "├──", [
1403 make_test!(str_searcher_empty_needle_empty_haystack, "", "", [
1406 make_test!(str_searcher_nonempty_needle_empty_haystack, "├", "", [
1408 make_test!(char_searcher_ascii_haystack, 'b', "abbcbbd", [
1417 make_test!(char_searcher_mulibyte_haystack, ' ', "├──", [
1422 make_test!(char_searcher_short_haystack, '\u{1F4A9}', "* \t", [
1430 macro_rules! generate_iterator_test {
1434 ($($arg:expr),*) -> [$($t:tt)*];
1437 with $fwd:expr, $bwd:expr;
1443 let res = vec![$($t)*];
1445 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1446 assert_eq!(fwd_vec, res);
1448 let mut bwd_vec: Vec<_> = ($bwd)($($arg),*).collect();
1450 assert_eq!(bwd_vec, res);
1458 ($($arg:expr),*) -> [$($t:tt)*];
1467 let res = vec![$($t)*];
1469 let fwd_vec: Vec<_> = ($fwd)($($arg),*).collect();
1470 assert_eq!(fwd_vec, res);
1477 generate_iterator_test! {
1478 double_ended_split {
1479 ("foo.bar.baz", '.') -> ["foo", "bar", "baz"];
1480 ("foo::bar::baz", "::") -> ["foo", "bar", "baz"];
1482 with str::split, str::rsplit;
1485 generate_iterator_test! {
1486 double_ended_split_terminator {
1487 ("foo;bar;baz;", ';') -> ["foo", "bar", "baz"];
1489 with str::split_terminator, str::rsplit_terminator;
1492 generate_iterator_test! {
1493 double_ended_matches {
1494 ("a1b2c3", char::is_numeric) -> ["1", "2", "3"];
1496 with str::matches, str::rmatches;
1499 generate_iterator_test! {
1500 double_ended_match_indices {
1501 ("a1b2c3", char::is_numeric) -> [(1, "1"), (3, "2"), (5, "3")];
1503 with str::match_indices, str::rmatch_indices;
1506 generate_iterator_test! {
1507 not_double_ended_splitn {
1508 ("foo::bar::baz", 2, "::") -> ["foo", "bar::baz"];
1513 generate_iterator_test! {
1514 not_double_ended_rsplitn {
1515 ("foo::bar::baz", 2, "::") -> ["baz", "foo::bar"];
1521 fn different_str_pattern_forwarding_lifetimes() {
1522 use std::str::pattern::Pattern;
1524 fn foo<'a, P>(p: P) where for<'b> &'b P: Pattern<'a> {