blob: b96d6524ee7b5d62abc89a76ca55f53e55f23e58 [file] [log] [blame]
David Tolnay55535012018-01-05 16:39:23 -08001// Copyright 2018 Syn Developers
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
Alex Crichton2e0229c2017-05-23 09:34:50 -07009#![cfg(feature = "extra-traits")]
Nika Layzella2a1a4a2017-11-19 11:33:17 -050010#![feature(rustc_private)]
11
David Tolnayb153dbc2016-10-04 23:39:10 -070012extern crate syn;
13use syn::*;
14
David Tolnaye7678922016-10-13 20:44:03 -070015#[macro_use]
16extern crate quote;
David Tolnayb153dbc2016-10-04 23:39:10 -070017
Alex Crichton605643b2017-07-05 18:35:14 -070018extern crate proc_macro2;
David Tolnayc5f1a652017-12-27 02:10:10 -050019use proc_macro2::{Span, Term, TokenStream};
Alex Crichton605643b2017-07-05 18:35:14 -070020
David Tolnaydd125562017-12-31 02:16:22 -050021#[macro_use]
22mod macros;
23
David Tolnayc7a5d3d2017-06-04 12:11:05 -070024mod common;
25
David Tolnayb153dbc2016-10-04 23:39:10 -070026#[test]
27fn test_split_for_impl() {
David Tolnaye7678922016-10-13 20:44:03 -070028 // <'a, 'b: 'a, #[may_dangle] T: 'a = ()> where T: Debug
David Tolnayc2f1aba2017-11-12 20:29:22 -080029 let generics = Generics {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070030 gt_token: Some(Default::default()),
31 lt_token: Some(Default::default()),
David Tolnayf2cfd722017-12-31 18:02:51 -050032 params: punctuated![
David Tolnayc2f1aba2017-11-12 20:29:22 -080033 GenericParam::Lifetime(LifetimeDef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070034 attrs: Default::default(),
David Tolnay66bb8d52018-01-08 08:22:31 -080035 lifetime: Lifetime::new(Term::intern("'a"), Span::def_site()),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070036 bounds: Default::default(),
37 colon_token: None,
David Tolnayc2f1aba2017-11-12 20:29:22 -080038 }),
39 GenericParam::Lifetime(LifetimeDef {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070040 attrs: Default::default(),
David Tolnay66bb8d52018-01-08 08:22:31 -080041 lifetime: Lifetime::new(Term::intern("'b"), Span::def_site()),
42 bounds: punctuated![Lifetime::new(Term::intern("'a"), Span::def_site())],
David Tolnay42eaae12017-12-26 23:05:18 -050043 colon_token: Some(token::Colon::default()),
David Tolnayc2f1aba2017-11-12 20:29:22 -080044 }),
45 GenericParam::Type(TypeParam {
David Tolnay51382052017-12-27 13:46:21 -050046 attrs: vec![
47 Attribute {
48 bracket_token: Default::default(),
49 pound_token: Default::default(),
50 style: AttrStyle::Outer,
51 path: "may_dangle".into(),
52 tts: TokenStream::empty(),
53 is_sugared_doc: false,
54 },
55 ],
Alex Crichtonccbb45d2017-05-23 10:58:24 -070056 ident: "T".into(),
David Tolnayf2cfd722017-12-31 18:02:51 -050057 bounds: punctuated![
David Tolnay66bb8d52018-01-08 08:22:31 -080058 TypeParamBound::Lifetime(Lifetime::new(Term::intern("'a"), Span::def_site())),
David Tolnaydd125562017-12-31 02:16:22 -050059 ],
David Tolnay51382052017-12-27 13:46:21 -050060 default: Some(
61 TypeTuple {
David Tolnayeadbda32017-12-29 02:33:47 -050062 elems: Default::default(),
David Tolnay51382052017-12-27 13:46:21 -050063 paren_token: Default::default(),
64 }.into(),
65 ),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070066 colon_token: Some(Default::default()),
67 eq_token: Default::default(),
David Tolnayc2f1aba2017-11-12 20:29:22 -080068 }),
David Tolnaydd125562017-12-31 02:16:22 -050069 ],
David Tolnayac997dd2017-12-27 23:18:22 -050070 where_clause: Some(WhereClause {
71 where_token: Default::default(),
David Tolnayf2cfd722017-12-31 18:02:51 -050072 predicates: punctuated![
David Tolnayd4add852018-01-01 20:13:24 -080073 WherePredicate::Type(PredicateType {
David Tolnay40fb8ce2018-01-02 10:53:46 -080074 lifetimes: None,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070075 colon_token: Default::default(),
David Tolnayfd6bf5c2017-11-12 09:41:14 -080076 bounded_ty: TypePath {
Alex Crichtonccbb45d2017-05-23 10:58:24 -070077 qself: None,
78 path: "T".into(),
79 }.into(),
David Tolnayf2cfd722017-12-31 18:02:51 -050080 bounds: punctuated![
David Tolnay40fb8ce2018-01-02 10:53:46 -080081 TypeParamBound::Trait(TraitBound {
82 modifier: TraitBoundModifier::None,
83 lifetimes: None,
84 path: "Debug".into(),
85 }),
David Tolnaydd125562017-12-31 02:16:22 -050086 ],
David Tolnay51382052017-12-27 13:46:21 -050087 }),
David Tolnaydd125562017-12-31 02:16:22 -050088 ],
David Tolnayac997dd2017-12-27 23:18:22 -050089 }),
David Tolnayb153dbc2016-10-04 23:39:10 -070090 };
91
92 let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
David Tolnaye7678922016-10-13 20:44:03 -070093 let tokens = quote! {
94 impl #impl_generics MyTrait for Test #ty_generics #where_clause {}
David Tolnayb153dbc2016-10-04 23:39:10 -070095 };
David Tolnay51382052017-12-27 13:46:21 -050096 let expected = concat!(
97 "impl < 'a , 'b : 'a , # [ may_dangle ] T : 'a > ",
98 "MyTrait for Test < 'a , 'b , T > ",
99 "where T : Debug { }"
100 );
David Tolnayc879a502017-01-25 15:51:32 -0800101 assert_eq!(expected, tokens.to_string());
David Tolnayb153dbc2016-10-04 23:39:10 -0700102
David Tolnayc879a502017-01-25 15:51:32 -0800103 let turbofish = ty_generics.as_turbofish();
104 let tokens = quote! {
105 Test #turbofish
106 };
107 let expected = "Test :: < 'a , 'b , T >";
David Tolnaye7678922016-10-13 20:44:03 -0700108 assert_eq!(expected, tokens.to_string());
David Tolnayb153dbc2016-10-04 23:39:10 -0700109}
David Tolnay23d83f92017-01-25 15:41:47 -0800110
111#[test]
112fn test_ty_param_bound() {
113 let tokens = quote!('a);
David Tolnay66bb8d52018-01-08 08:22:31 -0800114 let expected = TypeParamBound::Lifetime(Lifetime::new(Term::intern("'a"), Span::def_site()));
David Tolnay51382052017-12-27 13:46:21 -0500115 assert_eq!(
116 expected,
117 common::parse::syn::<TypeParamBound>(tokens.into())
118 );
David Tolnay23d83f92017-01-25 15:41:47 -0800119
Bastien Orivel340553a2018-02-15 23:57:38 +0100120 let tokens = quote!('_);
121 let expected = TypeParamBound::Lifetime(Lifetime::new(Term::intern("'_"), Span::def_site()));
122 assert_eq!(
123 expected,
124 common::parse::syn::<TypeParamBound>(tokens.into())
125 );
126
David Tolnay23d83f92017-01-25 15:41:47 -0800127 let tokens = quote!(Debug);
David Tolnay40fb8ce2018-01-02 10:53:46 -0800128 let expected = TypeParamBound::Trait(TraitBound {
129 modifier: TraitBoundModifier::None,
130 lifetimes: None,
131 path: "Debug".into(),
132 });
David Tolnay51382052017-12-27 13:46:21 -0500133 assert_eq!(
134 expected,
135 common::parse::syn::<TypeParamBound>(tokens.into())
136 );
David Tolnay23d83f92017-01-25 15:41:47 -0800137
138 let tokens = quote!(?Sized);
David Tolnay40fb8ce2018-01-02 10:53:46 -0800139 let expected = TypeParamBound::Trait(TraitBound {
140 modifier: TraitBoundModifier::Maybe(Default::default()),
141 lifetimes: None,
142 path: "Sized".into(),
143 });
David Tolnay51382052017-12-27 13:46:21 -0500144 assert_eq!(
145 expected,
146 common::parse::syn::<TypeParamBound>(tokens.into())
147 );
David Tolnay23d83f92017-01-25 15:41:47 -0800148}