blob: 112215add47ae4333b9627c3722ec4d85cd380bb [file] [log] [blame]
David Tolnaye7678922016-10-13 20:44:03 -07001extern crate quote;
David Tolnay7d8b3312019-03-10 01:26:11 -08002extern crate syn;
David Tolnayb153dbc2016-10-04 23:39:10 -07003
David Tolnay7d8b3312019-03-10 01:26:11 -08004mod features;
Alex Crichton605643b2017-07-05 18:35:14 -07005
David Tolnaydd125562017-12-31 02:16:22 -05006#[macro_use]
7mod macros;
8
David Tolnay7d8b3312019-03-10 01:26:11 -08009use quote::quote;
10use syn::{DeriveInput, ItemFn, TypeParamBound, WhereClause, WherePredicate};
Alex Crichtoneed4bc72018-05-17 10:59:15 -070011
David Tolnayb153dbc2016-10-04 23:39:10 -070012#[test]
13fn test_split_for_impl() {
David Tolnay7d8b3312019-03-10 01:26:11 -080014 let code = quote! {
15 struct S<'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug;
David Tolnayb153dbc2016-10-04 23:39:10 -070016 };
17
David Tolnay7d8b3312019-03-10 01:26:11 -080018 let actual = snapshot!(code as DeriveInput);
19
20 let generics = actual.generics;
David Tolnayb153dbc2016-10-04 23:39:10 -070021 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
David Tolnay7d8b3312019-03-10 01:26:11 -080022
23 let generated = quote! {
David Tolnaye7678922016-10-13 20:44:03 -070024 impl #impl_generics MyTrait for Test #ty_generics #where_clause {}
David Tolnayb153dbc2016-10-04 23:39:10 -070025 };
David Tolnay7d8b3312019-03-10 01:26:11 -080026 let expected = quote! {
27 impl<'a, 'b: 'a, #[may_dangle] T: 'a> MyTrait
28 for Test<'a, 'b, T>
29 where
30 T: Debug
31 {}
32 };
33 assert_eq!(generated.to_string(), expected.to_string());
David Tolnayb153dbc2016-10-04 23:39:10 -070034
David Tolnayc879a502017-01-25 15:51:32 -080035 let turbofish = ty_generics.as_turbofish();
David Tolnay7d8b3312019-03-10 01:26:11 -080036 let generated = quote! {
David Tolnayc879a502017-01-25 15:51:32 -080037 Test #turbofish
38 };
David Tolnay7d8b3312019-03-10 01:26:11 -080039 let expected = quote! {
40 Test::<'a, 'b, T>
41 };
42 assert_eq!(generated.to_string(), expected.to_string());
David Tolnayb153dbc2016-10-04 23:39:10 -070043}
David Tolnay23d83f92017-01-25 15:41:47 -080044
45#[test]
46fn test_ty_param_bound() {
47 let tokens = quote!('a);
David Tolnay7d8b3312019-03-10 01:26:11 -080048 snapshot!(tokens as TypeParamBound);
David Tolnay23d83f92017-01-25 15:41:47 -080049
Bastien Orivel340553a2018-02-15 23:57:38 +010050 let tokens = quote!('_);
David Tolnay7d8b3312019-03-10 01:26:11 -080051 snapshot!(tokens as TypeParamBound);
Bastien Orivel340553a2018-02-15 23:57:38 +010052
David Tolnay23d83f92017-01-25 15:41:47 -080053 let tokens = quote!(Debug);
David Tolnay7d8b3312019-03-10 01:26:11 -080054 snapshot!(tokens as TypeParamBound);
David Tolnay23d83f92017-01-25 15:41:47 -080055
56 let tokens = quote!(?Sized);
David Tolnay7d8b3312019-03-10 01:26:11 -080057 snapshot!(tokens as TypeParamBound);
David Tolnay23d83f92017-01-25 15:41:47 -080058}
Geoffry Songac02b182018-05-19 22:11:31 -070059
60#[test]
61fn test_fn_precedence_in_where_clause() {
David Tolnayc8b0e0f2019-03-07 22:46:32 -080062 // This should parse as two separate bounds, `FnOnce() -> i32` and `Send` - not
63 // `FnOnce() -> (i32 + Send)`.
David Tolnay7d8b3312019-03-10 01:26:11 -080064 let code = quote! {
David Tolnay65fb5662018-05-20 20:02:28 -070065 fn f<G>()
66 where
67 G: FnOnce() -> i32 + Send,
68 {
69 }
70 };
David Tolnay7d8b3312019-03-10 01:26:11 -080071
72 let actual = snapshot!(code as ItemFn);
73
74 let where_clause = actual.decl.generics.where_clause.as_ref().unwrap();
Geoffry Songac02b182018-05-19 22:11:31 -070075 assert_eq!(where_clause.predicates.len(), 1);
David Tolnay7d8b3312019-03-10 01:26:11 -080076
77 let predicate = match &where_clause.predicates[0] {
78 WherePredicate::Type(pred) => pred,
Geoffry Songac02b182018-05-19 22:11:31 -070079 _ => panic!("wrong predicate kind"),
80 };
David Tolnay7d8b3312019-03-10 01:26:11 -080081
Geoffry Songac02b182018-05-19 22:11:31 -070082 assert_eq!(predicate.bounds.len(), 2, "{:#?}", predicate.bounds);
David Tolnay7d8b3312019-03-10 01:26:11 -080083
Geoffry Songac02b182018-05-19 22:11:31 -070084 let first_bound = &predicate.bounds[0];
85 assert_eq!(quote!(#first_bound).to_string(), "FnOnce ( ) -> i32");
David Tolnay7d8b3312019-03-10 01:26:11 -080086
Geoffry Songac02b182018-05-19 22:11:31 -070087 let second_bound = &predicate.bounds[1];
88 assert_eq!(quote!(#second_bound).to_string(), "Send");
89}
David Tolnay38012de2018-09-02 13:32:47 -070090
91#[test]
92fn test_where_clause_at_end_of_input() {
93 let tokens = quote! {
94 where
95 };
David Tolnay7d8b3312019-03-10 01:26:11 -080096
97 let where_clause = snapshot!(tokens as WhereClause);
David Tolnay38012de2018-09-02 13:32:47 -070098 assert_eq!(where_clause.predicates.len(), 0);
99}