blob: 4b55b15ebcc28d1bf6e5c05f3cf77e5ccda13823 [file] [log] [blame]
Alex Crichton2e0229c2017-05-23 09:34:50 -07001#![cfg(feature = "extra-traits")]
Nika Layzella2a1a4a2017-11-19 11:33:17 -05002#![feature(rustc_private)]
3
David Tolnayb153dbc2016-10-04 23:39:10 -07004extern crate syn;
5use syn::*;
6
David Tolnaye7678922016-10-13 20:44:03 -07007#[macro_use]
8extern crate quote;
David Tolnayb153dbc2016-10-04 23:39:10 -07009
Alex Crichton605643b2017-07-05 18:35:14 -070010extern crate proc_macro2;
David Tolnayc5f1a652017-12-27 02:10:10 -050011use proc_macro2::{Span, Term, TokenStream};
Alex Crichton605643b2017-07-05 18:35:14 -070012
David Tolnaydd125562017-12-31 02:16:22 -050013#[macro_use]
14mod macros;
15
David Tolnayc7a5d3d2017-06-04 12:11:05 -070016mod common;
17
David Tolnayb153dbc2016-10-04 23:39:10 -070018#[test]
19fn test_split_for_impl() {
David Tolnaye7678922016-10-13 20:44:03 -070020 // <'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug
David Tolnayc2f1aba2017-11-12 20:29:22 -080021 let generics = Generics {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070022 gt_token: Some(Default::default()),
23 lt_token: Some(Default::default()),
David Tolnaydd125562017-12-31 02:16:22 -050024 params: delimited![
David Tolnayc2f1aba2017-11-12 20:29:22 -080025 GenericParam::Lifetime(LifetimeDef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070026 attrs: Default::default(),
Alex Crichton605643b2017-07-05 18:35:14 -070027 lifetime: Lifetime::new(Term::intern("'a"), Span::default()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070028 bounds: Default::default(),
29 colon_token: None,
David Tolnayc2f1aba2017-11-12 20:29:22 -080030 }),
31 GenericParam::Lifetime(LifetimeDef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070032 attrs: Default::default(),
Alex Crichton605643b2017-07-05 18:35:14 -070033 lifetime: Lifetime::new(Term::intern("'b"), Span::default()),
David Tolnaydd125562017-12-31 02:16:22 -050034 bounds: delimited![Lifetime::new(Term::intern("'a"), Span::default())],
David Tolnay42eaae12017-12-26 23:05:18 -050035 colon_token: Some(token::Colon::default()),
David Tolnayc2f1aba2017-11-12 20:29:22 -080036 }),
37 GenericParam::Type(TypeParam {
David Tolnay51382052017-12-27 13:46:21 -050038 attrs: vec![
39 Attribute {
40 bracket_token: Default::default(),
41 pound_token: Default::default(),
42 style: AttrStyle::Outer,
43 path: "may_dangle".into(),
44 tts: TokenStream::empty(),
45 is_sugared_doc: false,
46 },
47 ],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070048 ident: "T".into(),
David Tolnaydd125562017-12-31 02:16:22 -050049 bounds: delimited![
David Tolnay51382052017-12-27 13:46:21 -050050 TypeParamBound::Region(Lifetime::new(Term::intern("'a"), Span::default())),
David Tolnaydd125562017-12-31 02:16:22 -050051 ],
David Tolnay51382052017-12-27 13:46:21 -050052 default: Some(
53 TypeTuple {
David Tolnayeadbda32017-12-29 02:33:47 -050054 elems: Default::default(),
David Tolnay51382052017-12-27 13:46:21 -050055 paren_token: Default::default(),
56 }.into(),
57 ),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070058 colon_token: Some(Default::default()),
59 eq_token: Default::default(),
David Tolnayc2f1aba2017-11-12 20:29:22 -080060 }),
David Tolnaydd125562017-12-31 02:16:22 -050061 ],
David Tolnayac997dd2017-12-27 23:18:22 -050062 where_clause: Some(WhereClause {
63 where_token: Default::default(),
David Tolnaydd125562017-12-31 02:16:22 -050064 predicates: delimited![
Alex Crichtonccbb45d2017-05-23 10:58:24 -070065 WherePredicate::BoundPredicate(WhereBoundPredicate {
66 bound_lifetimes: None,
67 colon_token: Default::default(),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080068 bounded_ty: TypePath {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070069 qself: None,
70 path: "T".into(),
71 }.into(),
David Tolnaydd125562017-12-31 02:16:22 -050072 bounds: delimited![
David Tolnayfd6bf5c2017-11-12 09:41:14 -080073 TypeParamBound::Trait(
David Tolnayb153dbc2016-10-04 23:39:10 -070074 PolyTraitRef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070075 bound_lifetimes: None,
David Tolnaye7678922016-10-13 20:44:03 -070076 trait_ref: "Debug".into(),
David Tolnayb153dbc2016-10-04 23:39:10 -070077 },
78 TraitBoundModifier::None,
79 ),
David Tolnaydd125562017-12-31 02:16:22 -050080 ],
David Tolnay51382052017-12-27 13:46:21 -050081 }),
David Tolnaydd125562017-12-31 02:16:22 -050082 ],
David Tolnayac997dd2017-12-27 23:18:22 -050083 }),
David Tolnayb153dbc2016-10-04 23:39:10 -070084 };
85
86 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
David Tolnaye7678922016-10-13 20:44:03 -070087 let tokens = quote! {
88 impl #impl_generics MyTrait for Test #ty_generics #where_clause {}
David Tolnayb153dbc2016-10-04 23:39:10 -070089 };
David Tolnay51382052017-12-27 13:46:21 -050090 let expected = concat!(
91 "impl < 'a , 'b : 'a , # [ may_dangle ] T : 'a > ",
92 "MyTrait for Test < 'a , 'b , T > ",
93 "where T : Debug { }"
94 );
David Tolnayc879a502017-01-25 15:51:32 -080095 assert_eq!(expected, tokens.to_string());
David Tolnayb153dbc2016-10-04 23:39:10 -070096
David Tolnayc879a502017-01-25 15:51:32 -080097 let turbofish = ty_generics.as_turbofish();
98 let tokens = quote! {
99 Test #turbofish
100 };
101 let expected = "Test :: < 'a , 'b , T >";
David Tolnaye7678922016-10-13 20:44:03 -0700102 assert_eq!(expected, tokens.to_string());
David Tolnayb153dbc2016-10-04 23:39:10 -0700103}
David Tolnay23d83f92017-01-25 15:41:47 -0800104
105#[test]
106fn test_ty_param_bound() {
107 let tokens = quote!('a);
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800108 let expected = TypeParamBound::Region(Lifetime::new(Term::intern("'a"), Span::default()));
David Tolnay51382052017-12-27 13:46:21 -0500109 assert_eq!(
110 expected,
111 common::parse::syn::<TypeParamBound>(tokens.into())
112 );
David Tolnay23d83f92017-01-25 15:41:47 -0800113
114 let tokens = quote!(Debug);
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800115 let expected = TypeParamBound::Trait(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700116 PolyTraitRef {
117 bound_lifetimes: None,
118 trait_ref: "Debug".into(),
119 },
David Tolnay51382052017-12-27 13:46:21 -0500120 TraitBoundModifier::None,
121 );
122 assert_eq!(
123 expected,
124 common::parse::syn::<TypeParamBound>(tokens.into())
125 );
David Tolnay23d83f92017-01-25 15:41:47 -0800126
127 let tokens = quote!(?Sized);
David Tolnayfd6bf5c2017-11-12 09:41:14 -0800128 let expected = TypeParamBound::Trait(
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700129 PolyTraitRef {
130 bound_lifetimes: None,
131 trait_ref: "Sized".into(),
132 },
David Tolnay51382052017-12-27 13:46:21 -0500133 TraitBoundModifier::Maybe(Default::default()),
134 );
135 assert_eq!(
136 expected,
137 common::parse::syn::<TypeParamBound>(tokens.into())
138 );
David Tolnay23d83f92017-01-25 15:41:47 -0800139}