1
1
//! Builtin derives.
2
2
3
3
use base_db:: { CrateOrigin , LangCrateOrigin } ;
4
- use either:: Either ;
5
4
use tracing:: debug;
6
5
7
6
use crate :: tt:: { self , TokenId } ;
8
7
use syntax:: {
9
- ast:: { self , AstNode , HasGenericParams , HasModuleItem , HasName , HasTypeBounds } ,
8
+ ast:: { self , AstNode , HasGenericParams , HasModuleItem , HasName } ,
10
9
match_ast,
11
10
} ;
12
11
@@ -61,11 +60,8 @@ pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander>
61
60
62
61
struct BasicAdtInfo {
63
62
name : tt:: Ident ,
64
- /// first field is the name, and
65
- /// second field is `Some(ty)` if it's a const param of type `ty`, `None` if it's a type param.
66
- /// third fields is where bounds, if any
67
- param_types : Vec < ( tt:: Subtree , Option < tt:: Subtree > , Option < tt:: Subtree > ) > ,
68
- field_types : Vec < tt:: Subtree > ,
63
+ /// `Some(ty)` if it's a const param of type `ty`, `None` if it's a type param.
64
+ param_types : Vec < Option < tt:: Subtree > > ,
69
65
}
70
66
71
67
fn parse_adt ( tt : & tt:: Subtree ) -> Result < BasicAdtInfo , ExpandError > {
@@ -79,34 +75,17 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
79
75
ExpandError :: Other ( "no item found" . into ( ) )
80
76
} ) ?;
81
77
let node = item. syntax ( ) ;
82
- let ( name, params, fields ) = match_ast ! {
78
+ let ( name, params) = match_ast ! {
83
79
match node {
84
- ast:: Struct ( it) => {
85
- ( it. name( ) , it. generic_param_list( ) , it. field_list( ) . into_iter( ) . collect:: <Vec <_>>( ) )
86
- } ,
87
- ast:: Enum ( it) => ( it. name( ) , it. generic_param_list( ) , it. variant_list( ) . into_iter( ) . flat_map( |x| x. variants( ) ) . filter_map( |x| x. field_list( ) ) . collect( ) ) ,
88
- ast:: Union ( it) => ( it. name( ) , it. generic_param_list( ) , it. record_field_list( ) . into_iter( ) . map( |x| ast:: FieldList :: RecordFieldList ( x) ) . collect( ) ) ,
80
+ ast:: Struct ( it) => ( it. name( ) , it. generic_param_list( ) ) ,
81
+ ast:: Enum ( it) => ( it. name( ) , it. generic_param_list( ) ) ,
82
+ ast:: Union ( it) => ( it. name( ) , it. generic_param_list( ) ) ,
89
83
_ => {
90
84
debug!( "unexpected node is {:?}" , node) ;
91
85
return Err ( ExpandError :: Other ( "expected struct, enum or union" . into( ) ) )
92
86
} ,
93
87
}
94
88
} ;
95
- let field_types = fields
96
- . into_iter ( )
97
- . flat_map ( |f| match f {
98
- ast:: FieldList :: RecordFieldList ( x) => Either :: Left (
99
- x. fields ( )
100
- . filter_map ( |x| x. ty ( ) )
101
- . map ( |x| mbe:: syntax_node_to_token_tree ( x. syntax ( ) ) . 0 ) ,
102
- ) ,
103
- ast:: FieldList :: TupleFieldList ( x) => Either :: Right (
104
- x. fields ( )
105
- . filter_map ( |x| x. ty ( ) )
106
- . map ( |x| mbe:: syntax_node_to_token_tree ( x. syntax ( ) ) . 0 ) ,
107
- ) ,
108
- } )
109
- . collect :: < Vec < _ > > ( ) ;
110
89
let name = name. ok_or_else ( || {
111
90
debug ! ( "parsed item has no name" ) ;
112
91
ExpandError :: Other ( "missing name" . into ( ) )
@@ -118,46 +97,35 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
118
97
. into_iter ( )
119
98
. flat_map ( |param_list| param_list. type_or_const_params ( ) )
120
99
. map ( |param| {
121
- let name = param
122
- . name ( )
123
- . map ( |x| mbe:: syntax_node_to_token_tree ( x. syntax ( ) ) . 0 )
124
- . unwrap_or_else ( tt:: Subtree :: empty) ;
125
- let bounds = match & param {
126
- ast:: TypeOrConstParam :: Type ( x) => {
127
- x. type_bound_list ( ) . map ( |x| mbe:: syntax_node_to_token_tree ( x. syntax ( ) ) . 0 )
128
- }
129
- ast:: TypeOrConstParam :: Const ( _) => None ,
130
- } ;
131
- let ty = if let ast:: TypeOrConstParam :: Const ( param) = param {
100
+ if let ast:: TypeOrConstParam :: Const ( param) = param {
132
101
let ty = param
133
102
. ty ( )
134
103
. map ( |ty| mbe:: syntax_node_to_token_tree ( ty. syntax ( ) ) . 0 )
135
104
. unwrap_or_else ( tt:: Subtree :: empty) ;
136
105
Some ( ty)
137
106
} else {
138
107
None
139
- } ;
140
- ( name, ty, bounds)
108
+ }
141
109
} )
142
110
. collect ( ) ;
143
- Ok ( BasicAdtInfo { name : name_token, param_types, field_types } )
111
+ Ok ( BasicAdtInfo { name : name_token, param_types } )
144
112
}
145
113
146
114
fn expand_simple_derive ( tt : & tt:: Subtree , trait_path : tt:: Subtree ) -> ExpandResult < tt:: Subtree > {
147
115
let info = match parse_adt ( tt) {
148
116
Ok ( info) => info,
149
117
Err ( e) => return ExpandResult :: with_err ( tt:: Subtree :: empty ( ) , e) ,
150
118
} ;
151
- let mut where_block = vec ! [ ] ;
152
119
let ( params, args) : ( Vec < _ > , Vec < _ > ) = info
153
120
. param_types
154
121
. into_iter ( )
155
- . map ( |( ident, param_ty, bound) | {
122
+ . enumerate ( )
123
+ . map ( |( idx, param_ty) | {
124
+ let ident = tt:: Leaf :: Ident ( tt:: Ident {
125
+ span : tt:: TokenId :: unspecified ( ) ,
126
+ text : format ! ( "T{idx}" ) . into ( ) ,
127
+ } ) ;
156
128
let ident_ = ident. clone ( ) ;
157
- if let Some ( b) = bound {
158
- let ident = ident. clone ( ) ;
159
- where_block. push ( quote ! { #ident : #b , } ) ;
160
- }
161
129
if let Some ( ty) = param_ty {
162
130
( quote ! { const #ident : #ty , } , quote ! { #ident_ , } )
163
131
} else {
@@ -166,16 +134,9 @@ fn expand_simple_derive(tt: &tt::Subtree, trait_path: tt::Subtree) -> ExpandResu
166
134
}
167
135
} )
168
136
. unzip ( ) ;
169
-
170
- where_block. extend ( info. field_types . iter ( ) . map ( |x| {
171
- let x = x. clone ( ) ;
172
- let bound = trait_path. clone ( ) ;
173
- quote ! { #x : #bound , }
174
- } ) ) ;
175
-
176
137
let name = info. name ;
177
138
let expanded = quote ! {
178
- impl < ##params > #trait_path for #name < ##args > where ##where_block { }
139
+ impl < ##params > #trait_path for #name < ##args > { }
179
140
} ;
180
141
ExpandResult :: ok ( expanded)
181
142
}
0 commit comments