summaryrefslogtreecommitdiffstats
path: root/rust/vendor/syn-0.15.44/tests/test_generics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/vendor/syn-0.15.44/tests/test_generics.rs')
-rw-r--r--rust/vendor/syn-0.15.44/tests/test_generics.rs288
1 files changed, 288 insertions, 0 deletions
diff --git a/rust/vendor/syn-0.15.44/tests/test_generics.rs b/rust/vendor/syn-0.15.44/tests/test_generics.rs
new file mode 100644
index 0000000..27b204e
--- /dev/null
+++ b/rust/vendor/syn-0.15.44/tests/test_generics.rs
@@ -0,0 +1,288 @@
+extern crate quote;
+extern crate syn;
+
+mod features;
+
+#[macro_use]
+mod macros;
+
+use quote::quote;
+use syn::{DeriveInput, ItemFn, TypeParamBound, WhereClause, WherePredicate};
+
+#[test]
+fn test_split_for_impl() {
+ let input = quote! {
+ struct S<'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug;
+ };
+
+ snapshot!(input as DeriveInput, @r###"
+ ⋮DeriveInput {
+ ⋮ vis: Inherited,
+ ⋮ ident: "S",
+ ⋮ generics: Generics {
+ ⋮ lt_token: Some,
+ ⋮ params: [
+ ⋮ Lifetime(LifetimeDef {
+ ⋮ lifetime: Lifetime {
+ ⋮ ident: "a",
+ ⋮ },
+ ⋮ }),
+ ⋮ Lifetime(LifetimeDef {
+ ⋮ lifetime: Lifetime {
+ ⋮ ident: "b",
+ ⋮ },
+ ⋮ colon_token: Some,
+ ⋮ bounds: [
+ ⋮ Lifetime {
+ ⋮ ident: "a",
+ ⋮ },
+ ⋮ ],
+ ⋮ }),
+ ⋮ Type(TypeParam {
+ ⋮ attrs: [
+ ⋮ Attribute {
+ ⋮ style: Outer,
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "may_dangle",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ tts: ``,
+ ⋮ },
+ ⋮ ],
+ ⋮ ident: "T",
+ ⋮ colon_token: Some,
+ ⋮ bounds: [
+ ⋮ Lifetime(Lifetime {
+ ⋮ ident: "a",
+ ⋮ }),
+ ⋮ ],
+ ⋮ eq_token: Some,
+ ⋮ default: Some(Type::Tuple),
+ ⋮ }),
+ ⋮ ],
+ ⋮ gt_token: Some,
+ ⋮ where_clause: Some(WhereClause {
+ ⋮ predicates: [
+ ⋮ Type(PredicateType {
+ ⋮ bounded_ty: Type::Path {
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "T",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ },
+ ⋮ bounds: [
+ ⋮ Trait(TraitBound {
+ ⋮ modifier: None,
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "Debug",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ }),
+ ⋮ ],
+ ⋮ }),
+ ⋮ ],
+ ⋮ }),
+ ⋮ },
+ ⋮ data: Data::Struct {
+ ⋮ fields: Unit,
+ ⋮ semi_token: Some,
+ ⋮ },
+ ⋮}
+ "###);
+
+ let generics = input.generics;
+ let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+
+ let generated = quote! {
+ impl #impl_generics MyTrait for Test #ty_generics #where_clause {}
+ };
+ let expected = quote! {
+ impl<'a, 'b: 'a, #[may_dangle] T: 'a> MyTrait
+ for Test<'a, 'b, T>
+ where
+ T: Debug
+ {}
+ };
+ assert_eq!(generated.to_string(), expected.to_string());
+
+ let turbofish = ty_generics.as_turbofish();
+ let generated = quote! {
+ Test #turbofish
+ };
+ let expected = quote! {
+ Test::<'a, 'b, T>
+ };
+ assert_eq!(generated.to_string(), expected.to_string());
+}
+
+#[test]
+fn test_ty_param_bound() {
+ let tokens = quote!('a);
+ snapshot!(tokens as TypeParamBound, @r###"
+ ⋮Lifetime(Lifetime {
+ ⋮ ident: "a",
+ ⋮})
+ "###);
+
+ let tokens = quote!('_);
+ snapshot!(tokens as TypeParamBound, @r###"
+ ⋮Lifetime(Lifetime {
+ ⋮ ident: "_",
+ ⋮})
+ "###);
+
+ let tokens = quote!(Debug);
+ snapshot!(tokens as TypeParamBound, @r###"
+ ⋮Trait(TraitBound {
+ ⋮ modifier: None,
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "Debug",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮})
+ "###);
+
+ let tokens = quote!(?Sized);
+ snapshot!(tokens as TypeParamBound, @r###"
+ ⋮Trait(TraitBound {
+ ⋮ modifier: Maybe,
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "Sized",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮})
+ "###);
+}
+
+#[test]
+fn test_fn_precedence_in_where_clause() {
+ // This should parse as two separate bounds, `FnOnce() -> i32` and `Send` - not
+ // `FnOnce() -> (i32 + Send)`.
+ let input = quote! {
+ fn f<G>()
+ where
+ G: FnOnce() -> i32 + Send,
+ {
+ }
+ };
+
+ snapshot!(input as ItemFn, @r###"
+ ⋮ItemFn {
+ ⋮ vis: Inherited,
+ ⋮ ident: "f",
+ ⋮ decl: FnDecl {
+ ⋮ generics: Generics {
+ ⋮ lt_token: Some,
+ ⋮ params: [
+ ⋮ Type(TypeParam {
+ ⋮ ident: "G",
+ ⋮ }),
+ ⋮ ],
+ ⋮ gt_token: Some,
+ ⋮ where_clause: Some(WhereClause {
+ ⋮ predicates: [
+ ⋮ Type(PredicateType {
+ ⋮ bounded_ty: Type::Path {
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "G",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ },
+ ⋮ bounds: [
+ ⋮ Trait(TraitBound {
+ ⋮ modifier: None,
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "FnOnce",
+ ⋮ arguments: PathArguments::Parenthesized {
+ ⋮ output: Type(
+ ⋮ Type::Path {
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "i32",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ },
+ ⋮ ),
+ ⋮ },
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ }),
+ ⋮ Trait(TraitBound {
+ ⋮ modifier: None,
+ ⋮ path: Path {
+ ⋮ segments: [
+ ⋮ PathSegment {
+ ⋮ ident: "Send",
+ ⋮ arguments: None,
+ ⋮ },
+ ⋮ ],
+ ⋮ },
+ ⋮ }),
+ ⋮ ],
+ ⋮ }),
+ ⋮ ],
+ ⋮ }),
+ ⋮ },
+ ⋮ output: Default,
+ ⋮ },
+ ⋮ block: Block,
+ ⋮}
+ "###);
+
+ let where_clause = input.decl.generics.where_clause.as_ref().unwrap();
+ assert_eq!(where_clause.predicates.len(), 1);
+
+ let predicate = match &where_clause.predicates[0] {
+ WherePredicate::Type(pred) => pred,
+ _ => panic!("wrong predicate kind"),
+ };
+
+ assert_eq!(predicate.bounds.len(), 2, "{:#?}", predicate.bounds);
+
+ let first_bound = &predicate.bounds[0];
+ assert_eq!(quote!(#first_bound).to_string(), "FnOnce ( ) -> i32");
+
+ let second_bound = &predicate.bounds[1];
+ assert_eq!(quote!(#second_bound).to_string(), "Send");
+}
+
+#[test]
+fn test_where_clause_at_end_of_input() {
+ let input = quote! {
+ where
+ };
+
+ snapshot!(input as WhereClause, @"WhereClause");
+
+ assert_eq!(input.predicates.len(), 0);
+}