test_path.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. #[macro_use]
  2. mod macros;
  3. use proc_macro2::{Delimiter, Group, Ident, Punct, Spacing, Span, TokenStream, TokenTree};
  4. use quote::{quote, ToTokens};
  5. use std::iter::FromIterator;
  6. use syn::{parse_quote, Expr, Type, TypePath};
  7. #[test]
  8. fn parse_interpolated_leading_component() {
  9. // mimics the token stream corresponding to `$mod::rest`
  10. let tokens = TokenStream::from_iter(vec![
  11. TokenTree::Group(Group::new(Delimiter::None, quote! { first })),
  12. TokenTree::Punct(Punct::new(':', Spacing::Joint)),
  13. TokenTree::Punct(Punct::new(':', Spacing::Alone)),
  14. TokenTree::Ident(Ident::new("rest", Span::call_site())),
  15. ]);
  16. snapshot!(tokens.clone() as Expr, @r###"
  17. Expr::Path {
  18. path: Path {
  19. segments: [
  20. PathSegment {
  21. ident: "first",
  22. arguments: None,
  23. },
  24. PathSegment {
  25. ident: "rest",
  26. arguments: None,
  27. },
  28. ],
  29. },
  30. }
  31. "###);
  32. snapshot!(tokens as Type, @r###"
  33. Type::Path {
  34. path: Path {
  35. segments: [
  36. PathSegment {
  37. ident: "first",
  38. arguments: None,
  39. },
  40. PathSegment {
  41. ident: "rest",
  42. arguments: None,
  43. },
  44. ],
  45. },
  46. }
  47. "###);
  48. }
  49. #[test]
  50. fn print_incomplete_qpath() {
  51. // qpath with `as` token
  52. let mut ty: TypePath = parse_quote!(<Self as A>::Q);
  53. snapshot!(ty.to_token_stream(), @r###"
  54. TokenStream(`< Self as A > :: Q`)
  55. "###);
  56. assert!(ty.path.segments.pop().is_some());
  57. snapshot!(ty.to_token_stream(), @r###"
  58. TokenStream(`< Self as A > ::`)
  59. "###);
  60. assert!(ty.path.segments.pop().is_some());
  61. snapshot!(ty.to_token_stream(), @r###"
  62. TokenStream(`< Self >`)
  63. "###);
  64. assert!(ty.path.segments.pop().is_none());
  65. // qpath without `as` token
  66. let mut ty: TypePath = parse_quote!(<Self>::A::B);
  67. snapshot!(ty.to_token_stream(), @r###"
  68. TokenStream(`< Self > :: A :: B`)
  69. "###);
  70. assert!(ty.path.segments.pop().is_some());
  71. snapshot!(ty.to_token_stream(), @r###"
  72. TokenStream(`< Self > :: A ::`)
  73. "###);
  74. assert!(ty.path.segments.pop().is_some());
  75. snapshot!(ty.to_token_stream(), @r###"
  76. TokenStream(`< Self > ::`)
  77. "###);
  78. assert!(ty.path.segments.pop().is_none());
  79. // normal path
  80. let mut ty: TypePath = parse_quote!(Self::A::B);
  81. snapshot!(ty.to_token_stream(), @r###"
  82. TokenStream(`Self :: A :: B`)
  83. "###);
  84. assert!(ty.path.segments.pop().is_some());
  85. snapshot!(ty.to_token_stream(), @r###"
  86. TokenStream(`Self :: A ::`)
  87. "###);
  88. assert!(ty.path.segments.pop().is_some());
  89. snapshot!(ty.to_token_stream(), @r###"
  90. TokenStream(`Self ::`)
  91. "###);
  92. assert!(ty.path.segments.pop().is_some());
  93. snapshot!(ty.to_token_stream(), @r###"
  94. TokenStream(``)
  95. "###);
  96. assert!(ty.path.segments.pop().is_none());
  97. }
  98. #[test]
  99. fn parse_parenthesized_path_arguments_with_disambiguator() {
  100. #[rustfmt::skip]
  101. let tokens = quote!(FnOnce::() -> !);
  102. snapshot!(tokens as Type, @r###"
  103. Type::Path {
  104. path: Path {
  105. segments: [
  106. PathSegment {
  107. ident: "FnOnce",
  108. arguments: PathArguments::Parenthesized {
  109. output: Type(
  110. Type::Never,
  111. ),
  112. },
  113. },
  114. ],
  115. },
  116. }
  117. "###);
  118. }