17ac06127Sopenharmony_ci#![allow( 27ac06127Sopenharmony_ci clippy::assertions_on_result_states, 37ac06127Sopenharmony_ci clippy::items_after_statements, 47ac06127Sopenharmony_ci clippy::non_ascii_literal, 57ac06127Sopenharmony_ci clippy::octal_escapes 67ac06127Sopenharmony_ci)] 77ac06127Sopenharmony_ci 87ac06127Sopenharmony_ciuse proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree}; 97ac06127Sopenharmony_ciuse std::iter; 107ac06127Sopenharmony_ciuse std::str::{self, FromStr}; 117ac06127Sopenharmony_ci 127ac06127Sopenharmony_ci#[test] 137ac06127Sopenharmony_cifn idents() { 147ac06127Sopenharmony_ci assert_eq!( 157ac06127Sopenharmony_ci Ident::new("String", Span::call_site()).to_string(), 167ac06127Sopenharmony_ci "String" 177ac06127Sopenharmony_ci ); 187ac06127Sopenharmony_ci assert_eq!(Ident::new("fn", Span::call_site()).to_string(), "fn"); 197ac06127Sopenharmony_ci assert_eq!(Ident::new("_", Span::call_site()).to_string(), "_"); 207ac06127Sopenharmony_ci} 217ac06127Sopenharmony_ci 227ac06127Sopenharmony_ci#[test] 237ac06127Sopenharmony_cifn raw_idents() { 247ac06127Sopenharmony_ci assert_eq!( 257ac06127Sopenharmony_ci Ident::new_raw("String", Span::call_site()).to_string(), 267ac06127Sopenharmony_ci "r#String" 277ac06127Sopenharmony_ci ); 287ac06127Sopenharmony_ci assert_eq!(Ident::new_raw("fn", Span::call_site()).to_string(), "r#fn"); 297ac06127Sopenharmony_ci} 307ac06127Sopenharmony_ci 317ac06127Sopenharmony_ci#[test] 327ac06127Sopenharmony_ci#[should_panic(expected = "`r#_` cannot be a raw identifier")] 337ac06127Sopenharmony_cifn ident_raw_underscore() { 347ac06127Sopenharmony_ci Ident::new_raw("_", Span::call_site()); 357ac06127Sopenharmony_ci} 367ac06127Sopenharmony_ci 377ac06127Sopenharmony_ci#[test] 387ac06127Sopenharmony_ci#[should_panic(expected = "`r#super` cannot be a raw identifier")] 397ac06127Sopenharmony_cifn ident_raw_reserved() { 407ac06127Sopenharmony_ci Ident::new_raw("super", Span::call_site()); 417ac06127Sopenharmony_ci} 427ac06127Sopenharmony_ci 437ac06127Sopenharmony_ci#[test] 447ac06127Sopenharmony_ci#[should_panic(expected = "Ident is not allowed to be empty; use Option<Ident>")] 457ac06127Sopenharmony_cifn ident_empty() { 467ac06127Sopenharmony_ci Ident::new("", Span::call_site()); 477ac06127Sopenharmony_ci} 487ac06127Sopenharmony_ci 497ac06127Sopenharmony_ci#[test] 507ac06127Sopenharmony_ci#[should_panic(expected = "Ident cannot be a number; use Literal instead")] 517ac06127Sopenharmony_cifn ident_number() { 527ac06127Sopenharmony_ci Ident::new("255", Span::call_site()); 537ac06127Sopenharmony_ci} 547ac06127Sopenharmony_ci 557ac06127Sopenharmony_ci#[test] 567ac06127Sopenharmony_ci#[should_panic(expected = "\"a#\" is not a valid Ident")] 577ac06127Sopenharmony_cifn ident_invalid() { 587ac06127Sopenharmony_ci Ident::new("a#", Span::call_site()); 597ac06127Sopenharmony_ci} 607ac06127Sopenharmony_ci 617ac06127Sopenharmony_ci#[test] 627ac06127Sopenharmony_ci#[should_panic(expected = "not a valid Ident")] 637ac06127Sopenharmony_cifn raw_ident_empty() { 647ac06127Sopenharmony_ci Ident::new("r#", Span::call_site()); 657ac06127Sopenharmony_ci} 667ac06127Sopenharmony_ci 677ac06127Sopenharmony_ci#[test] 687ac06127Sopenharmony_ci#[should_panic(expected = "not a valid Ident")] 697ac06127Sopenharmony_cifn raw_ident_number() { 707ac06127Sopenharmony_ci Ident::new("r#255", Span::call_site()); 717ac06127Sopenharmony_ci} 727ac06127Sopenharmony_ci 737ac06127Sopenharmony_ci#[test] 747ac06127Sopenharmony_ci#[should_panic(expected = "\"r#a#\" is not a valid Ident")] 757ac06127Sopenharmony_cifn raw_ident_invalid() { 767ac06127Sopenharmony_ci Ident::new("r#a#", Span::call_site()); 777ac06127Sopenharmony_ci} 787ac06127Sopenharmony_ci 797ac06127Sopenharmony_ci#[test] 807ac06127Sopenharmony_ci#[should_panic(expected = "not a valid Ident")] 817ac06127Sopenharmony_cifn lifetime_empty() { 827ac06127Sopenharmony_ci Ident::new("'", Span::call_site()); 837ac06127Sopenharmony_ci} 847ac06127Sopenharmony_ci 857ac06127Sopenharmony_ci#[test] 867ac06127Sopenharmony_ci#[should_panic(expected = "not a valid Ident")] 877ac06127Sopenharmony_cifn lifetime_number() { 887ac06127Sopenharmony_ci Ident::new("'255", Span::call_site()); 897ac06127Sopenharmony_ci} 907ac06127Sopenharmony_ci 917ac06127Sopenharmony_ci#[test] 927ac06127Sopenharmony_ci#[should_panic(expected = r#""'a#" is not a valid Ident"#)] 937ac06127Sopenharmony_cifn lifetime_invalid() { 947ac06127Sopenharmony_ci Ident::new("'a#", Span::call_site()); 957ac06127Sopenharmony_ci} 967ac06127Sopenharmony_ci 977ac06127Sopenharmony_ci#[test] 987ac06127Sopenharmony_cifn literal_string() { 997ac06127Sopenharmony_ci assert_eq!(Literal::string("foo").to_string(), "\"foo\""); 1007ac06127Sopenharmony_ci assert_eq!(Literal::string("\"").to_string(), "\"\\\"\""); 1017ac06127Sopenharmony_ci assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); 1027ac06127Sopenharmony_ci assert_eq!( 1037ac06127Sopenharmony_ci Literal::string("a\00b\07c\08d\0e\0").to_string(), 1047ac06127Sopenharmony_ci "\"a\\x000b\\x007c\\08d\\0e\\0\"", 1057ac06127Sopenharmony_ci ); 1067ac06127Sopenharmony_ci 1077ac06127Sopenharmony_ci "\"\\\r\n x\"".parse::<TokenStream>().unwrap(); 1087ac06127Sopenharmony_ci "\"\\\r\n \rx\"".parse::<TokenStream>().unwrap_err(); 1097ac06127Sopenharmony_ci} 1107ac06127Sopenharmony_ci 1117ac06127Sopenharmony_ci#[test] 1127ac06127Sopenharmony_cifn literal_raw_string() { 1137ac06127Sopenharmony_ci "r\"\r\n\"".parse::<TokenStream>().unwrap(); 1147ac06127Sopenharmony_ci 1157ac06127Sopenharmony_ci fn raw_string_literal_with_hashes(n: usize) -> String { 1167ac06127Sopenharmony_ci let mut literal = String::new(); 1177ac06127Sopenharmony_ci literal.push('r'); 1187ac06127Sopenharmony_ci literal.extend(iter::repeat('#').take(n)); 1197ac06127Sopenharmony_ci literal.push('"'); 1207ac06127Sopenharmony_ci literal.push('"'); 1217ac06127Sopenharmony_ci literal.extend(iter::repeat('#').take(n)); 1227ac06127Sopenharmony_ci literal 1237ac06127Sopenharmony_ci } 1247ac06127Sopenharmony_ci 1257ac06127Sopenharmony_ci raw_string_literal_with_hashes(255) 1267ac06127Sopenharmony_ci .parse::<TokenStream>() 1277ac06127Sopenharmony_ci .unwrap(); 1287ac06127Sopenharmony_ci 1297ac06127Sopenharmony_ci // https://github.com/rust-lang/rust/pull/95251 1307ac06127Sopenharmony_ci raw_string_literal_with_hashes(256) 1317ac06127Sopenharmony_ci .parse::<TokenStream>() 1327ac06127Sopenharmony_ci .unwrap_err(); 1337ac06127Sopenharmony_ci} 1347ac06127Sopenharmony_ci 1357ac06127Sopenharmony_ci#[test] 1367ac06127Sopenharmony_cifn literal_byte_string() { 1377ac06127Sopenharmony_ci assert_eq!(Literal::byte_string(b"").to_string(), "b\"\""); 1387ac06127Sopenharmony_ci assert_eq!( 1397ac06127Sopenharmony_ci Literal::byte_string(b"\0\t\n\r\"\\2\x10").to_string(), 1407ac06127Sopenharmony_ci "b\"\\0\\t\\n\\r\\\"\\\\2\\x10\"", 1417ac06127Sopenharmony_ci ); 1427ac06127Sopenharmony_ci assert_eq!( 1437ac06127Sopenharmony_ci Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(), 1447ac06127Sopenharmony_ci "b\"a\\x000b\\x007c\\08d\\0e\\0\"", 1457ac06127Sopenharmony_ci ); 1467ac06127Sopenharmony_ci 1477ac06127Sopenharmony_ci "b\"\\\r\n x\"".parse::<TokenStream>().unwrap(); 1487ac06127Sopenharmony_ci "b\"\\\r\n \rx\"".parse::<TokenStream>().unwrap_err(); 1497ac06127Sopenharmony_ci "b\"\\\r\n \u{a0}x\"".parse::<TokenStream>().unwrap_err(); 1507ac06127Sopenharmony_ci "br\"\u{a0}\"".parse::<TokenStream>().unwrap_err(); 1517ac06127Sopenharmony_ci} 1527ac06127Sopenharmony_ci 1537ac06127Sopenharmony_ci#[test] 1547ac06127Sopenharmony_cifn literal_c_string() { 1557ac06127Sopenharmony_ci let strings = r###" 1567ac06127Sopenharmony_ci c"hello\x80我叫\u{1F980}" // from the RFC 1577ac06127Sopenharmony_ci cr"\" 1587ac06127Sopenharmony_ci cr##"Hello "world"!"## 1597ac06127Sopenharmony_ci c"\t\n\r\"\\" 1607ac06127Sopenharmony_ci "###; 1617ac06127Sopenharmony_ci 1627ac06127Sopenharmony_ci let mut tokens = strings.parse::<TokenStream>().unwrap().into_iter(); 1637ac06127Sopenharmony_ci 1647ac06127Sopenharmony_ci for expected in &[ 1657ac06127Sopenharmony_ci r#"c"hello\x80我叫\u{1F980}""#, 1667ac06127Sopenharmony_ci r#"cr"\""#, 1677ac06127Sopenharmony_ci r###"cr##"Hello "world"!"##"###, 1687ac06127Sopenharmony_ci r#"c"\t\n\r\"\\""#, 1697ac06127Sopenharmony_ci ] { 1707ac06127Sopenharmony_ci match tokens.next().unwrap() { 1717ac06127Sopenharmony_ci TokenTree::Literal(literal) => { 1727ac06127Sopenharmony_ci assert_eq!(literal.to_string(), *expected); 1737ac06127Sopenharmony_ci } 1747ac06127Sopenharmony_ci unexpected => panic!("unexpected token: {:?}", unexpected), 1757ac06127Sopenharmony_ci } 1767ac06127Sopenharmony_ci } 1777ac06127Sopenharmony_ci 1787ac06127Sopenharmony_ci if let Some(unexpected) = tokens.next() { 1797ac06127Sopenharmony_ci panic!("unexpected token: {:?}", unexpected); 1807ac06127Sopenharmony_ci } 1817ac06127Sopenharmony_ci 1827ac06127Sopenharmony_ci for invalid in &[r#"c"\0""#, r#"c"\x00""#, r#"c"\u{0}""#, "c\"\0\""] { 1837ac06127Sopenharmony_ci if let Ok(unexpected) = invalid.parse::<TokenStream>() { 1847ac06127Sopenharmony_ci panic!("unexpected token: {:?}", unexpected); 1857ac06127Sopenharmony_ci } 1867ac06127Sopenharmony_ci } 1877ac06127Sopenharmony_ci} 1887ac06127Sopenharmony_ci 1897ac06127Sopenharmony_ci#[test] 1907ac06127Sopenharmony_cifn literal_character() { 1917ac06127Sopenharmony_ci assert_eq!(Literal::character('x').to_string(), "'x'"); 1927ac06127Sopenharmony_ci assert_eq!(Literal::character('\'').to_string(), "'\\''"); 1937ac06127Sopenharmony_ci assert_eq!(Literal::character('"').to_string(), "'\"'"); 1947ac06127Sopenharmony_ci} 1957ac06127Sopenharmony_ci 1967ac06127Sopenharmony_ci#[test] 1977ac06127Sopenharmony_cifn literal_integer() { 1987ac06127Sopenharmony_ci assert_eq!(Literal::u8_suffixed(10).to_string(), "10u8"); 1997ac06127Sopenharmony_ci assert_eq!(Literal::u16_suffixed(10).to_string(), "10u16"); 2007ac06127Sopenharmony_ci assert_eq!(Literal::u32_suffixed(10).to_string(), "10u32"); 2017ac06127Sopenharmony_ci assert_eq!(Literal::u64_suffixed(10).to_string(), "10u64"); 2027ac06127Sopenharmony_ci assert_eq!(Literal::u128_suffixed(10).to_string(), "10u128"); 2037ac06127Sopenharmony_ci assert_eq!(Literal::usize_suffixed(10).to_string(), "10usize"); 2047ac06127Sopenharmony_ci 2057ac06127Sopenharmony_ci assert_eq!(Literal::i8_suffixed(10).to_string(), "10i8"); 2067ac06127Sopenharmony_ci assert_eq!(Literal::i16_suffixed(10).to_string(), "10i16"); 2077ac06127Sopenharmony_ci assert_eq!(Literal::i32_suffixed(10).to_string(), "10i32"); 2087ac06127Sopenharmony_ci assert_eq!(Literal::i64_suffixed(10).to_string(), "10i64"); 2097ac06127Sopenharmony_ci assert_eq!(Literal::i128_suffixed(10).to_string(), "10i128"); 2107ac06127Sopenharmony_ci assert_eq!(Literal::isize_suffixed(10).to_string(), "10isize"); 2117ac06127Sopenharmony_ci 2127ac06127Sopenharmony_ci assert_eq!(Literal::u8_unsuffixed(10).to_string(), "10"); 2137ac06127Sopenharmony_ci assert_eq!(Literal::u16_unsuffixed(10).to_string(), "10"); 2147ac06127Sopenharmony_ci assert_eq!(Literal::u32_unsuffixed(10).to_string(), "10"); 2157ac06127Sopenharmony_ci assert_eq!(Literal::u64_unsuffixed(10).to_string(), "10"); 2167ac06127Sopenharmony_ci assert_eq!(Literal::u128_unsuffixed(10).to_string(), "10"); 2177ac06127Sopenharmony_ci assert_eq!(Literal::usize_unsuffixed(10).to_string(), "10"); 2187ac06127Sopenharmony_ci 2197ac06127Sopenharmony_ci assert_eq!(Literal::i8_unsuffixed(10).to_string(), "10"); 2207ac06127Sopenharmony_ci assert_eq!(Literal::i16_unsuffixed(10).to_string(), "10"); 2217ac06127Sopenharmony_ci assert_eq!(Literal::i32_unsuffixed(10).to_string(), "10"); 2227ac06127Sopenharmony_ci assert_eq!(Literal::i64_unsuffixed(10).to_string(), "10"); 2237ac06127Sopenharmony_ci assert_eq!(Literal::i128_unsuffixed(10).to_string(), "10"); 2247ac06127Sopenharmony_ci assert_eq!(Literal::isize_unsuffixed(10).to_string(), "10"); 2257ac06127Sopenharmony_ci} 2267ac06127Sopenharmony_ci 2277ac06127Sopenharmony_ci#[test] 2287ac06127Sopenharmony_cifn literal_float() { 2297ac06127Sopenharmony_ci assert_eq!(Literal::f32_suffixed(10.0).to_string(), "10f32"); 2307ac06127Sopenharmony_ci assert_eq!(Literal::f64_suffixed(10.0).to_string(), "10f64"); 2317ac06127Sopenharmony_ci 2327ac06127Sopenharmony_ci assert_eq!(Literal::f32_unsuffixed(10.0).to_string(), "10.0"); 2337ac06127Sopenharmony_ci assert_eq!(Literal::f64_unsuffixed(10.0).to_string(), "10.0"); 2347ac06127Sopenharmony_ci} 2357ac06127Sopenharmony_ci 2367ac06127Sopenharmony_ci#[test] 2377ac06127Sopenharmony_cifn literal_suffix() { 2387ac06127Sopenharmony_ci fn token_count(p: &str) -> usize { 2397ac06127Sopenharmony_ci p.parse::<TokenStream>().unwrap().into_iter().count() 2407ac06127Sopenharmony_ci } 2417ac06127Sopenharmony_ci 2427ac06127Sopenharmony_ci assert_eq!(token_count("999u256"), 1); 2437ac06127Sopenharmony_ci assert_eq!(token_count("999r#u256"), 3); 2447ac06127Sopenharmony_ci assert_eq!(token_count("1."), 1); 2457ac06127Sopenharmony_ci assert_eq!(token_count("1.f32"), 3); 2467ac06127Sopenharmony_ci assert_eq!(token_count("1.0_0"), 1); 2477ac06127Sopenharmony_ci assert_eq!(token_count("1._0"), 3); 2487ac06127Sopenharmony_ci assert_eq!(token_count("1._m"), 3); 2497ac06127Sopenharmony_ci assert_eq!(token_count("\"\"s"), 1); 2507ac06127Sopenharmony_ci assert_eq!(token_count("r\"\"r"), 1); 2517ac06127Sopenharmony_ci assert_eq!(token_count("b\"\"b"), 1); 2527ac06127Sopenharmony_ci assert_eq!(token_count("br\"\"br"), 1); 2537ac06127Sopenharmony_ci assert_eq!(token_count("r#\"\"#r"), 1); 2547ac06127Sopenharmony_ci assert_eq!(token_count("'c'c"), 1); 2557ac06127Sopenharmony_ci assert_eq!(token_count("b'b'b"), 1); 2567ac06127Sopenharmony_ci assert_eq!(token_count("0E"), 1); 2577ac06127Sopenharmony_ci assert_eq!(token_count("0o0A"), 1); 2587ac06127Sopenharmony_ci assert_eq!(token_count("0E--0"), 4); 2597ac06127Sopenharmony_ci assert_eq!(token_count("0.0ECMA"), 1); 2607ac06127Sopenharmony_ci} 2617ac06127Sopenharmony_ci 2627ac06127Sopenharmony_ci#[test] 2637ac06127Sopenharmony_cifn literal_iter_negative() { 2647ac06127Sopenharmony_ci let negative_literal = Literal::i32_suffixed(-3); 2657ac06127Sopenharmony_ci let tokens = TokenStream::from(TokenTree::Literal(negative_literal)); 2667ac06127Sopenharmony_ci let mut iter = tokens.into_iter(); 2677ac06127Sopenharmony_ci match iter.next().unwrap() { 2687ac06127Sopenharmony_ci TokenTree::Punct(punct) => { 2697ac06127Sopenharmony_ci assert_eq!(punct.as_char(), '-'); 2707ac06127Sopenharmony_ci assert_eq!(punct.spacing(), Spacing::Alone); 2717ac06127Sopenharmony_ci } 2727ac06127Sopenharmony_ci unexpected => panic!("unexpected token {:?}", unexpected), 2737ac06127Sopenharmony_ci } 2747ac06127Sopenharmony_ci match iter.next().unwrap() { 2757ac06127Sopenharmony_ci TokenTree::Literal(literal) => { 2767ac06127Sopenharmony_ci assert_eq!(literal.to_string(), "3i32"); 2777ac06127Sopenharmony_ci } 2787ac06127Sopenharmony_ci unexpected => panic!("unexpected token {:?}", unexpected), 2797ac06127Sopenharmony_ci } 2807ac06127Sopenharmony_ci assert!(iter.next().is_none()); 2817ac06127Sopenharmony_ci} 2827ac06127Sopenharmony_ci 2837ac06127Sopenharmony_ci#[test] 2847ac06127Sopenharmony_cifn literal_parse() { 2857ac06127Sopenharmony_ci assert!("1".parse::<Literal>().is_ok()); 2867ac06127Sopenharmony_ci assert!("-1".parse::<Literal>().is_ok()); 2877ac06127Sopenharmony_ci assert!("-1u12".parse::<Literal>().is_ok()); 2887ac06127Sopenharmony_ci assert!("1.0".parse::<Literal>().is_ok()); 2897ac06127Sopenharmony_ci assert!("-1.0".parse::<Literal>().is_ok()); 2907ac06127Sopenharmony_ci assert!("-1.0f12".parse::<Literal>().is_ok()); 2917ac06127Sopenharmony_ci assert!("'a'".parse::<Literal>().is_ok()); 2927ac06127Sopenharmony_ci assert!("\"\n\"".parse::<Literal>().is_ok()); 2937ac06127Sopenharmony_ci assert!("0 1".parse::<Literal>().is_err()); 2947ac06127Sopenharmony_ci assert!(" 0".parse::<Literal>().is_err()); 2957ac06127Sopenharmony_ci assert!("0 ".parse::<Literal>().is_err()); 2967ac06127Sopenharmony_ci assert!("/* comment */0".parse::<Literal>().is_err()); 2977ac06127Sopenharmony_ci assert!("0/* comment */".parse::<Literal>().is_err()); 2987ac06127Sopenharmony_ci assert!("0// comment".parse::<Literal>().is_err()); 2997ac06127Sopenharmony_ci assert!("- 1".parse::<Literal>().is_err()); 3007ac06127Sopenharmony_ci assert!("- 1.0".parse::<Literal>().is_err()); 3017ac06127Sopenharmony_ci assert!("-\"\"".parse::<Literal>().is_err()); 3027ac06127Sopenharmony_ci} 3037ac06127Sopenharmony_ci 3047ac06127Sopenharmony_ci#[test] 3057ac06127Sopenharmony_cifn literal_span() { 3067ac06127Sopenharmony_ci let positive = "0.1".parse::<Literal>().unwrap(); 3077ac06127Sopenharmony_ci let negative = "-0.1".parse::<Literal>().unwrap(); 3087ac06127Sopenharmony_ci let subspan = positive.subspan(1..2); 3097ac06127Sopenharmony_ci 3107ac06127Sopenharmony_ci #[cfg(not(span_locations))] 3117ac06127Sopenharmony_ci { 3127ac06127Sopenharmony_ci let _ = negative; 3137ac06127Sopenharmony_ci assert!(subspan.is_none()); 3147ac06127Sopenharmony_ci } 3157ac06127Sopenharmony_ci 3167ac06127Sopenharmony_ci #[cfg(span_locations)] 3177ac06127Sopenharmony_ci { 3187ac06127Sopenharmony_ci assert_eq!(positive.span().start().column, 0); 3197ac06127Sopenharmony_ci assert_eq!(positive.span().end().column, 3); 3207ac06127Sopenharmony_ci assert_eq!(negative.span().start().column, 0); 3217ac06127Sopenharmony_ci assert_eq!(negative.span().end().column, 4); 3227ac06127Sopenharmony_ci assert_eq!(subspan.unwrap().source_text().unwrap(), "."); 3237ac06127Sopenharmony_ci } 3247ac06127Sopenharmony_ci 3257ac06127Sopenharmony_ci assert!(positive.subspan(1..4).is_none()); 3267ac06127Sopenharmony_ci} 3277ac06127Sopenharmony_ci 3287ac06127Sopenharmony_ci#[cfg(span_locations)] 3297ac06127Sopenharmony_ci#[test] 3307ac06127Sopenharmony_cifn source_text() { 3317ac06127Sopenharmony_ci let input = " a z "; 3327ac06127Sopenharmony_ci let mut tokens = input 3337ac06127Sopenharmony_ci .parse::<proc_macro2::TokenStream>() 3347ac06127Sopenharmony_ci .unwrap() 3357ac06127Sopenharmony_ci .into_iter(); 3367ac06127Sopenharmony_ci 3377ac06127Sopenharmony_ci let first = tokens.next().unwrap(); 3387ac06127Sopenharmony_ci assert_eq!("", first.span().source_text().unwrap()); 3397ac06127Sopenharmony_ci 3407ac06127Sopenharmony_ci let second = tokens.next().unwrap(); 3417ac06127Sopenharmony_ci let third = tokens.next().unwrap(); 3427ac06127Sopenharmony_ci assert_eq!("z", third.span().source_text().unwrap()); 3437ac06127Sopenharmony_ci assert_eq!("a", second.span().source_text().unwrap()); 3447ac06127Sopenharmony_ci} 3457ac06127Sopenharmony_ci 3467ac06127Sopenharmony_ci#[test] 3477ac06127Sopenharmony_cifn roundtrip() { 3487ac06127Sopenharmony_ci fn roundtrip(p: &str) { 3497ac06127Sopenharmony_ci println!("parse: {}", p); 3507ac06127Sopenharmony_ci let s = p.parse::<TokenStream>().unwrap().to_string(); 3517ac06127Sopenharmony_ci println!("first: {}", s); 3527ac06127Sopenharmony_ci let s2 = s.parse::<TokenStream>().unwrap().to_string(); 3537ac06127Sopenharmony_ci assert_eq!(s, s2); 3547ac06127Sopenharmony_ci } 3557ac06127Sopenharmony_ci roundtrip("a"); 3567ac06127Sopenharmony_ci roundtrip("<<"); 3577ac06127Sopenharmony_ci roundtrip("<<="); 3587ac06127Sopenharmony_ci roundtrip( 3597ac06127Sopenharmony_ci " 3607ac06127Sopenharmony_ci 1 3617ac06127Sopenharmony_ci 1.0 3627ac06127Sopenharmony_ci 1f32 3637ac06127Sopenharmony_ci 2f64 3647ac06127Sopenharmony_ci 1usize 3657ac06127Sopenharmony_ci 4isize 3667ac06127Sopenharmony_ci 4e10 3677ac06127Sopenharmony_ci 1_000 3687ac06127Sopenharmony_ci 1_0i32 3697ac06127Sopenharmony_ci 8u8 3707ac06127Sopenharmony_ci 9 3717ac06127Sopenharmony_ci 0 3727ac06127Sopenharmony_ci 0xffffffffffffffffffffffffffffffff 3737ac06127Sopenharmony_ci 1x 3747ac06127Sopenharmony_ci 1u80 3757ac06127Sopenharmony_ci 1f320 3767ac06127Sopenharmony_ci ", 3777ac06127Sopenharmony_ci ); 3787ac06127Sopenharmony_ci roundtrip("'a"); 3797ac06127Sopenharmony_ci roundtrip("'_"); 3807ac06127Sopenharmony_ci roundtrip("'static"); 3817ac06127Sopenharmony_ci roundtrip("'\\u{10__FFFF}'"); 3827ac06127Sopenharmony_ci roundtrip("\"\\u{10_F0FF__}foo\\u{1_0_0_0__}\""); 3837ac06127Sopenharmony_ci} 3847ac06127Sopenharmony_ci 3857ac06127Sopenharmony_ci#[test] 3867ac06127Sopenharmony_cifn fail() { 3877ac06127Sopenharmony_ci fn fail(p: &str) { 3887ac06127Sopenharmony_ci if let Ok(s) = p.parse::<TokenStream>() { 3897ac06127Sopenharmony_ci panic!("should have failed to parse: {}\n{:#?}", p, s); 3907ac06127Sopenharmony_ci } 3917ac06127Sopenharmony_ci } 3927ac06127Sopenharmony_ci fail("' static"); 3937ac06127Sopenharmony_ci fail("r#1"); 3947ac06127Sopenharmony_ci fail("r#_"); 3957ac06127Sopenharmony_ci fail("\"\\u{0000000}\""); // overlong unicode escape (rust allows at most 6 hex digits) 3967ac06127Sopenharmony_ci fail("\"\\u{999999}\""); // outside of valid range of char 3977ac06127Sopenharmony_ci fail("\"\\u{_0}\""); // leading underscore 3987ac06127Sopenharmony_ci fail("\"\\u{}\""); // empty 3997ac06127Sopenharmony_ci fail("b\"\r\""); // bare carriage return in byte string 4007ac06127Sopenharmony_ci fail("r\"\r\""); // bare carriage return in raw string 4017ac06127Sopenharmony_ci fail("\"\\\r \""); // backslash carriage return 4027ac06127Sopenharmony_ci fail("'aa'aa"); 4037ac06127Sopenharmony_ci fail("br##\"\"#"); 4047ac06127Sopenharmony_ci fail("\"\\\n\u{85}\r\""); 4057ac06127Sopenharmony_ci} 4067ac06127Sopenharmony_ci 4077ac06127Sopenharmony_ci#[cfg(span_locations)] 4087ac06127Sopenharmony_ci#[test] 4097ac06127Sopenharmony_cifn span_test() { 4107ac06127Sopenharmony_ci check_spans( 4117ac06127Sopenharmony_ci "\ 4127ac06127Sopenharmony_ci/// This is a document comment 4137ac06127Sopenharmony_citesting 123 4147ac06127Sopenharmony_ci{ 4157ac06127Sopenharmony_ci testing 234 4167ac06127Sopenharmony_ci}", 4177ac06127Sopenharmony_ci &[ 4187ac06127Sopenharmony_ci (1, 0, 1, 30), // # 4197ac06127Sopenharmony_ci (1, 0, 1, 30), // [ ... ] 4207ac06127Sopenharmony_ci (1, 0, 1, 30), // doc 4217ac06127Sopenharmony_ci (1, 0, 1, 30), // = 4227ac06127Sopenharmony_ci (1, 0, 1, 30), // "This is..." 4237ac06127Sopenharmony_ci (2, 0, 2, 7), // testing 4247ac06127Sopenharmony_ci (2, 8, 2, 11), // 123 4257ac06127Sopenharmony_ci (3, 0, 5, 1), // { ... } 4267ac06127Sopenharmony_ci (4, 2, 4, 9), // testing 4277ac06127Sopenharmony_ci (4, 10, 4, 13), // 234 4287ac06127Sopenharmony_ci ], 4297ac06127Sopenharmony_ci ); 4307ac06127Sopenharmony_ci} 4317ac06127Sopenharmony_ci 4327ac06127Sopenharmony_ci#[cfg(procmacro2_semver_exempt)] 4337ac06127Sopenharmony_ci#[cfg(not(nightly))] 4347ac06127Sopenharmony_ci#[test] 4357ac06127Sopenharmony_cifn default_span() { 4367ac06127Sopenharmony_ci let start = Span::call_site().start(); 4377ac06127Sopenharmony_ci assert_eq!(start.line, 1); 4387ac06127Sopenharmony_ci assert_eq!(start.column, 0); 4397ac06127Sopenharmony_ci let end = Span::call_site().end(); 4407ac06127Sopenharmony_ci assert_eq!(end.line, 1); 4417ac06127Sopenharmony_ci assert_eq!(end.column, 0); 4427ac06127Sopenharmony_ci let source_file = Span::call_site().source_file(); 4437ac06127Sopenharmony_ci assert_eq!(source_file.path().to_string_lossy(), "<unspecified>"); 4447ac06127Sopenharmony_ci assert!(!source_file.is_real()); 4457ac06127Sopenharmony_ci} 4467ac06127Sopenharmony_ci 4477ac06127Sopenharmony_ci#[cfg(procmacro2_semver_exempt)] 4487ac06127Sopenharmony_ci#[test] 4497ac06127Sopenharmony_cifn span_join() { 4507ac06127Sopenharmony_ci let source1 = "aaa\nbbb" 4517ac06127Sopenharmony_ci .parse::<TokenStream>() 4527ac06127Sopenharmony_ci .unwrap() 4537ac06127Sopenharmony_ci .into_iter() 4547ac06127Sopenharmony_ci .collect::<Vec<_>>(); 4557ac06127Sopenharmony_ci let source2 = "ccc\nddd" 4567ac06127Sopenharmony_ci .parse::<TokenStream>() 4577ac06127Sopenharmony_ci .unwrap() 4587ac06127Sopenharmony_ci .into_iter() 4597ac06127Sopenharmony_ci .collect::<Vec<_>>(); 4607ac06127Sopenharmony_ci 4617ac06127Sopenharmony_ci assert!(source1[0].span().source_file() != source2[0].span().source_file()); 4627ac06127Sopenharmony_ci assert_eq!( 4637ac06127Sopenharmony_ci source1[0].span().source_file(), 4647ac06127Sopenharmony_ci source1[1].span().source_file() 4657ac06127Sopenharmony_ci ); 4667ac06127Sopenharmony_ci 4677ac06127Sopenharmony_ci let joined1 = source1[0].span().join(source1[1].span()); 4687ac06127Sopenharmony_ci let joined2 = source1[0].span().join(source2[0].span()); 4697ac06127Sopenharmony_ci assert!(joined1.is_some()); 4707ac06127Sopenharmony_ci assert!(joined2.is_none()); 4717ac06127Sopenharmony_ci 4727ac06127Sopenharmony_ci let start = joined1.unwrap().start(); 4737ac06127Sopenharmony_ci let end = joined1.unwrap().end(); 4747ac06127Sopenharmony_ci assert_eq!(start.line, 1); 4757ac06127Sopenharmony_ci assert_eq!(start.column, 0); 4767ac06127Sopenharmony_ci assert_eq!(end.line, 2); 4777ac06127Sopenharmony_ci assert_eq!(end.column, 3); 4787ac06127Sopenharmony_ci 4797ac06127Sopenharmony_ci assert_eq!( 4807ac06127Sopenharmony_ci joined1.unwrap().source_file(), 4817ac06127Sopenharmony_ci source1[0].span().source_file() 4827ac06127Sopenharmony_ci ); 4837ac06127Sopenharmony_ci} 4847ac06127Sopenharmony_ci 4857ac06127Sopenharmony_ci#[test] 4867ac06127Sopenharmony_cifn no_panic() { 4877ac06127Sopenharmony_ci let s = str::from_utf8(b"b\'\xc2\x86 \x00\x00\x00^\"").unwrap(); 4887ac06127Sopenharmony_ci assert!(s.parse::<TokenStream>().is_err()); 4897ac06127Sopenharmony_ci} 4907ac06127Sopenharmony_ci 4917ac06127Sopenharmony_ci#[test] 4927ac06127Sopenharmony_cifn punct_before_comment() { 4937ac06127Sopenharmony_ci let mut tts = TokenStream::from_str("~// comment").unwrap().into_iter(); 4947ac06127Sopenharmony_ci match tts.next().unwrap() { 4957ac06127Sopenharmony_ci TokenTree::Punct(tt) => { 4967ac06127Sopenharmony_ci assert_eq!(tt.as_char(), '~'); 4977ac06127Sopenharmony_ci assert_eq!(tt.spacing(), Spacing::Alone); 4987ac06127Sopenharmony_ci } 4997ac06127Sopenharmony_ci wrong => panic!("wrong token {:?}", wrong), 5007ac06127Sopenharmony_ci } 5017ac06127Sopenharmony_ci} 5027ac06127Sopenharmony_ci 5037ac06127Sopenharmony_ci#[test] 5047ac06127Sopenharmony_cifn joint_last_token() { 5057ac06127Sopenharmony_ci // This test verifies that we match the behavior of libproc_macro *not* in 5067ac06127Sopenharmony_ci // the range nightly-2020-09-06 through nightly-2020-09-10, in which this 5077ac06127Sopenharmony_ci // behavior was temporarily broken. 5087ac06127Sopenharmony_ci // See https://github.com/rust-lang/rust/issues/76399 5097ac06127Sopenharmony_ci 5107ac06127Sopenharmony_ci let joint_punct = Punct::new(':', Spacing::Joint); 5117ac06127Sopenharmony_ci let stream = TokenStream::from(TokenTree::Punct(joint_punct)); 5127ac06127Sopenharmony_ci let punct = match stream.into_iter().next().unwrap() { 5137ac06127Sopenharmony_ci TokenTree::Punct(punct) => punct, 5147ac06127Sopenharmony_ci _ => unreachable!(), 5157ac06127Sopenharmony_ci }; 5167ac06127Sopenharmony_ci assert_eq!(punct.spacing(), Spacing::Joint); 5177ac06127Sopenharmony_ci} 5187ac06127Sopenharmony_ci 5197ac06127Sopenharmony_ci#[test] 5207ac06127Sopenharmony_cifn raw_identifier() { 5217ac06127Sopenharmony_ci let mut tts = TokenStream::from_str("r#dyn").unwrap().into_iter(); 5227ac06127Sopenharmony_ci match tts.next().unwrap() { 5237ac06127Sopenharmony_ci TokenTree::Ident(raw) => assert_eq!("r#dyn", raw.to_string()), 5247ac06127Sopenharmony_ci wrong => panic!("wrong token {:?}", wrong), 5257ac06127Sopenharmony_ci } 5267ac06127Sopenharmony_ci assert!(tts.next().is_none()); 5277ac06127Sopenharmony_ci} 5287ac06127Sopenharmony_ci 5297ac06127Sopenharmony_ci#[test] 5307ac06127Sopenharmony_cifn test_debug_ident() { 5317ac06127Sopenharmony_ci let ident = Ident::new("proc_macro", Span::call_site()); 5327ac06127Sopenharmony_ci 5337ac06127Sopenharmony_ci #[cfg(not(span_locations))] 5347ac06127Sopenharmony_ci let expected = "Ident(proc_macro)"; 5357ac06127Sopenharmony_ci 5367ac06127Sopenharmony_ci #[cfg(span_locations)] 5377ac06127Sopenharmony_ci let expected = "Ident { sym: proc_macro }"; 5387ac06127Sopenharmony_ci 5397ac06127Sopenharmony_ci assert_eq!(expected, format!("{:?}", ident)); 5407ac06127Sopenharmony_ci} 5417ac06127Sopenharmony_ci 5427ac06127Sopenharmony_ci#[test] 5437ac06127Sopenharmony_cifn test_debug_tokenstream() { 5447ac06127Sopenharmony_ci let tts = TokenStream::from_str("[a + 1]").unwrap(); 5457ac06127Sopenharmony_ci 5467ac06127Sopenharmony_ci #[cfg(not(span_locations))] 5477ac06127Sopenharmony_ci let expected = "\ 5487ac06127Sopenharmony_ciTokenStream [ 5497ac06127Sopenharmony_ci Group { 5507ac06127Sopenharmony_ci delimiter: Bracket, 5517ac06127Sopenharmony_ci stream: TokenStream [ 5527ac06127Sopenharmony_ci Ident { 5537ac06127Sopenharmony_ci sym: a, 5547ac06127Sopenharmony_ci }, 5557ac06127Sopenharmony_ci Punct { 5567ac06127Sopenharmony_ci char: '+', 5577ac06127Sopenharmony_ci spacing: Alone, 5587ac06127Sopenharmony_ci }, 5597ac06127Sopenharmony_ci Literal { 5607ac06127Sopenharmony_ci lit: 1, 5617ac06127Sopenharmony_ci }, 5627ac06127Sopenharmony_ci ], 5637ac06127Sopenharmony_ci }, 5647ac06127Sopenharmony_ci]\ 5657ac06127Sopenharmony_ci "; 5667ac06127Sopenharmony_ci 5677ac06127Sopenharmony_ci #[cfg(not(span_locations))] 5687ac06127Sopenharmony_ci let expected_before_trailing_commas = "\ 5697ac06127Sopenharmony_ciTokenStream [ 5707ac06127Sopenharmony_ci Group { 5717ac06127Sopenharmony_ci delimiter: Bracket, 5727ac06127Sopenharmony_ci stream: TokenStream [ 5737ac06127Sopenharmony_ci Ident { 5747ac06127Sopenharmony_ci sym: a 5757ac06127Sopenharmony_ci }, 5767ac06127Sopenharmony_ci Punct { 5777ac06127Sopenharmony_ci char: '+', 5787ac06127Sopenharmony_ci spacing: Alone 5797ac06127Sopenharmony_ci }, 5807ac06127Sopenharmony_ci Literal { 5817ac06127Sopenharmony_ci lit: 1 5827ac06127Sopenharmony_ci } 5837ac06127Sopenharmony_ci ] 5847ac06127Sopenharmony_ci } 5857ac06127Sopenharmony_ci]\ 5867ac06127Sopenharmony_ci "; 5877ac06127Sopenharmony_ci 5887ac06127Sopenharmony_ci #[cfg(span_locations)] 5897ac06127Sopenharmony_ci let expected = "\ 5907ac06127Sopenharmony_ciTokenStream [ 5917ac06127Sopenharmony_ci Group { 5927ac06127Sopenharmony_ci delimiter: Bracket, 5937ac06127Sopenharmony_ci stream: TokenStream [ 5947ac06127Sopenharmony_ci Ident { 5957ac06127Sopenharmony_ci sym: a, 5967ac06127Sopenharmony_ci span: bytes(2..3), 5977ac06127Sopenharmony_ci }, 5987ac06127Sopenharmony_ci Punct { 5997ac06127Sopenharmony_ci char: '+', 6007ac06127Sopenharmony_ci spacing: Alone, 6017ac06127Sopenharmony_ci span: bytes(4..5), 6027ac06127Sopenharmony_ci }, 6037ac06127Sopenharmony_ci Literal { 6047ac06127Sopenharmony_ci lit: 1, 6057ac06127Sopenharmony_ci span: bytes(6..7), 6067ac06127Sopenharmony_ci }, 6077ac06127Sopenharmony_ci ], 6087ac06127Sopenharmony_ci span: bytes(1..8), 6097ac06127Sopenharmony_ci }, 6107ac06127Sopenharmony_ci]\ 6117ac06127Sopenharmony_ci "; 6127ac06127Sopenharmony_ci 6137ac06127Sopenharmony_ci #[cfg(span_locations)] 6147ac06127Sopenharmony_ci let expected_before_trailing_commas = "\ 6157ac06127Sopenharmony_ciTokenStream [ 6167ac06127Sopenharmony_ci Group { 6177ac06127Sopenharmony_ci delimiter: Bracket, 6187ac06127Sopenharmony_ci stream: TokenStream [ 6197ac06127Sopenharmony_ci Ident { 6207ac06127Sopenharmony_ci sym: a, 6217ac06127Sopenharmony_ci span: bytes(2..3) 6227ac06127Sopenharmony_ci }, 6237ac06127Sopenharmony_ci Punct { 6247ac06127Sopenharmony_ci char: '+', 6257ac06127Sopenharmony_ci spacing: Alone, 6267ac06127Sopenharmony_ci span: bytes(4..5) 6277ac06127Sopenharmony_ci }, 6287ac06127Sopenharmony_ci Literal { 6297ac06127Sopenharmony_ci lit: 1, 6307ac06127Sopenharmony_ci span: bytes(6..7) 6317ac06127Sopenharmony_ci } 6327ac06127Sopenharmony_ci ], 6337ac06127Sopenharmony_ci span: bytes(1..8) 6347ac06127Sopenharmony_ci } 6357ac06127Sopenharmony_ci]\ 6367ac06127Sopenharmony_ci "; 6377ac06127Sopenharmony_ci 6387ac06127Sopenharmony_ci let actual = format!("{:#?}", tts); 6397ac06127Sopenharmony_ci if actual.ends_with(",\n]") { 6407ac06127Sopenharmony_ci assert_eq!(expected, actual); 6417ac06127Sopenharmony_ci } else { 6427ac06127Sopenharmony_ci assert_eq!(expected_before_trailing_commas, actual); 6437ac06127Sopenharmony_ci } 6447ac06127Sopenharmony_ci} 6457ac06127Sopenharmony_ci 6467ac06127Sopenharmony_ci#[test] 6477ac06127Sopenharmony_cifn default_tokenstream_is_empty() { 6487ac06127Sopenharmony_ci let default_token_stream = <TokenStream as Default>::default(); 6497ac06127Sopenharmony_ci 6507ac06127Sopenharmony_ci assert!(default_token_stream.is_empty()); 6517ac06127Sopenharmony_ci} 6527ac06127Sopenharmony_ci 6537ac06127Sopenharmony_ci#[test] 6547ac06127Sopenharmony_cifn tokenstream_size_hint() { 6557ac06127Sopenharmony_ci let tokens = "a b (c d) e".parse::<TokenStream>().unwrap(); 6567ac06127Sopenharmony_ci 6577ac06127Sopenharmony_ci assert_eq!(tokens.into_iter().size_hint(), (4, Some(4))); 6587ac06127Sopenharmony_ci} 6597ac06127Sopenharmony_ci 6607ac06127Sopenharmony_ci#[test] 6617ac06127Sopenharmony_cifn tuple_indexing() { 6627ac06127Sopenharmony_ci // This behavior may change depending on https://github.com/rust-lang/rust/pull/71322 6637ac06127Sopenharmony_ci let mut tokens = "tuple.0.0".parse::<TokenStream>().unwrap().into_iter(); 6647ac06127Sopenharmony_ci assert_eq!("tuple", tokens.next().unwrap().to_string()); 6657ac06127Sopenharmony_ci assert_eq!(".", tokens.next().unwrap().to_string()); 6667ac06127Sopenharmony_ci assert_eq!("0.0", tokens.next().unwrap().to_string()); 6677ac06127Sopenharmony_ci assert!(tokens.next().is_none()); 6687ac06127Sopenharmony_ci} 6697ac06127Sopenharmony_ci 6707ac06127Sopenharmony_ci#[cfg(span_locations)] 6717ac06127Sopenharmony_ci#[test] 6727ac06127Sopenharmony_cifn non_ascii_tokens() { 6737ac06127Sopenharmony_ci check_spans("// abc", &[]); 6747ac06127Sopenharmony_ci check_spans("// ábc", &[]); 6757ac06127Sopenharmony_ci check_spans("// abc x", &[]); 6767ac06127Sopenharmony_ci check_spans("// ábc x", &[]); 6777ac06127Sopenharmony_ci check_spans("/* abc */ x", &[(1, 10, 1, 11)]); 6787ac06127Sopenharmony_ci check_spans("/* ábc */ x", &[(1, 10, 1, 11)]); 6797ac06127Sopenharmony_ci check_spans("/* ab\nc */ x", &[(2, 5, 2, 6)]); 6807ac06127Sopenharmony_ci check_spans("/* áb\nc */ x", &[(2, 5, 2, 6)]); 6817ac06127Sopenharmony_ci check_spans("/*** abc */ x", &[(1, 12, 1, 13)]); 6827ac06127Sopenharmony_ci check_spans("/*** ábc */ x", &[(1, 12, 1, 13)]); 6837ac06127Sopenharmony_ci check_spans(r#""abc""#, &[(1, 0, 1, 5)]); 6847ac06127Sopenharmony_ci check_spans(r#""ábc""#, &[(1, 0, 1, 5)]); 6857ac06127Sopenharmony_ci check_spans(r##"r#"abc"#"##, &[(1, 0, 1, 8)]); 6867ac06127Sopenharmony_ci check_spans(r##"r#"ábc"#"##, &[(1, 0, 1, 8)]); 6877ac06127Sopenharmony_ci check_spans("r#\"a\nc\"#", &[(1, 0, 2, 3)]); 6887ac06127Sopenharmony_ci check_spans("r#\"á\nc\"#", &[(1, 0, 2, 3)]); 6897ac06127Sopenharmony_ci check_spans("'a'", &[(1, 0, 1, 3)]); 6907ac06127Sopenharmony_ci check_spans("'á'", &[(1, 0, 1, 3)]); 6917ac06127Sopenharmony_ci check_spans("//! abc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); 6927ac06127Sopenharmony_ci check_spans("//! ábc", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); 6937ac06127Sopenharmony_ci check_spans("//! abc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); 6947ac06127Sopenharmony_ci check_spans("//! ábc\n", &[(1, 0, 1, 7), (1, 0, 1, 7), (1, 0, 1, 7)]); 6957ac06127Sopenharmony_ci check_spans("/*! abc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); 6967ac06127Sopenharmony_ci check_spans("/*! ábc */", &[(1, 0, 1, 10), (1, 0, 1, 10), (1, 0, 1, 10)]); 6977ac06127Sopenharmony_ci check_spans("/*! a\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); 6987ac06127Sopenharmony_ci check_spans("/*! á\nc */", &[(1, 0, 2, 4), (1, 0, 2, 4), (1, 0, 2, 4)]); 6997ac06127Sopenharmony_ci check_spans("abc", &[(1, 0, 1, 3)]); 7007ac06127Sopenharmony_ci check_spans("ábc", &[(1, 0, 1, 3)]); 7017ac06127Sopenharmony_ci check_spans("ábć", &[(1, 0, 1, 3)]); 7027ac06127Sopenharmony_ci check_spans("abc// foo", &[(1, 0, 1, 3)]); 7037ac06127Sopenharmony_ci check_spans("ábc// foo", &[(1, 0, 1, 3)]); 7047ac06127Sopenharmony_ci check_spans("ábć// foo", &[(1, 0, 1, 3)]); 7057ac06127Sopenharmony_ci check_spans("b\"a\\\n c\"", &[(1, 0, 2, 3)]); 7067ac06127Sopenharmony_ci} 7077ac06127Sopenharmony_ci 7087ac06127Sopenharmony_ci#[cfg(span_locations)] 7097ac06127Sopenharmony_cifn check_spans(p: &str, mut lines: &[(usize, usize, usize, usize)]) { 7107ac06127Sopenharmony_ci let ts = p.parse::<TokenStream>().unwrap(); 7117ac06127Sopenharmony_ci check_spans_internal(ts, &mut lines); 7127ac06127Sopenharmony_ci assert!(lines.is_empty(), "leftover ranges: {:?}", lines); 7137ac06127Sopenharmony_ci} 7147ac06127Sopenharmony_ci 7157ac06127Sopenharmony_ci#[cfg(span_locations)] 7167ac06127Sopenharmony_cifn check_spans_internal(ts: TokenStream, lines: &mut &[(usize, usize, usize, usize)]) { 7177ac06127Sopenharmony_ci for i in ts { 7187ac06127Sopenharmony_ci if let Some((&(sline, scol, eline, ecol), rest)) = lines.split_first() { 7197ac06127Sopenharmony_ci *lines = rest; 7207ac06127Sopenharmony_ci 7217ac06127Sopenharmony_ci let start = i.span().start(); 7227ac06127Sopenharmony_ci assert_eq!(start.line, sline, "sline did not match for {}", i); 7237ac06127Sopenharmony_ci assert_eq!(start.column, scol, "scol did not match for {}", i); 7247ac06127Sopenharmony_ci 7257ac06127Sopenharmony_ci let end = i.span().end(); 7267ac06127Sopenharmony_ci assert_eq!(end.line, eline, "eline did not match for {}", i); 7277ac06127Sopenharmony_ci assert_eq!(end.column, ecol, "ecol did not match for {}", i); 7287ac06127Sopenharmony_ci 7297ac06127Sopenharmony_ci if let TokenTree::Group(g) = i { 7307ac06127Sopenharmony_ci check_spans_internal(g.stream().clone(), lines); 7317ac06127Sopenharmony_ci } 7327ac06127Sopenharmony_ci } 7337ac06127Sopenharmony_ci } 7347ac06127Sopenharmony_ci} 7357ac06127Sopenharmony_ci 7367ac06127Sopenharmony_ci#[test] 7377ac06127Sopenharmony_cifn whitespace() { 7387ac06127Sopenharmony_ci // space, horizontal tab, vertical tab, form feed, carriage return, line 7397ac06127Sopenharmony_ci // feed, non-breaking space, left-to-right mark, right-to-left mark 7407ac06127Sopenharmony_ci let various_spaces = " \t\u{b}\u{c}\r\n\u{a0}\u{200e}\u{200f}"; 7417ac06127Sopenharmony_ci let tokens = various_spaces.parse::<TokenStream>().unwrap(); 7427ac06127Sopenharmony_ci assert_eq!(tokens.into_iter().count(), 0); 7437ac06127Sopenharmony_ci 7447ac06127Sopenharmony_ci let lone_carriage_returns = " \r \r\r\n "; 7457ac06127Sopenharmony_ci lone_carriage_returns.parse::<TokenStream>().unwrap(); 7467ac06127Sopenharmony_ci} 7477ac06127Sopenharmony_ci 7487ac06127Sopenharmony_ci#[test] 7497ac06127Sopenharmony_cifn byte_order_mark() { 7507ac06127Sopenharmony_ci let string = "\u{feff}foo"; 7517ac06127Sopenharmony_ci let tokens = string.parse::<TokenStream>().unwrap(); 7527ac06127Sopenharmony_ci match tokens.into_iter().next().unwrap() { 7537ac06127Sopenharmony_ci TokenTree::Ident(ident) => assert_eq!(ident, "foo"), 7547ac06127Sopenharmony_ci _ => unreachable!(), 7557ac06127Sopenharmony_ci } 7567ac06127Sopenharmony_ci 7577ac06127Sopenharmony_ci let string = "foo\u{feff}"; 7587ac06127Sopenharmony_ci string.parse::<TokenStream>().unwrap_err(); 7597ac06127Sopenharmony_ci} 760