11//! Builtin derives.
22
33use base_db:: { CrateOrigin , LangCrateOrigin } ;
4- use either:: Either ;
54use tracing:: debug;
65
76use crate :: tt:: { self , TokenId } ;
87use syntax:: {
9- ast:: { self , AstNode , HasGenericParams , HasModuleItem , HasName , HasTypeBounds } ,
8+ ast:: { self , AstNode , HasGenericParams , HasModuleItem , HasName } ,
109 match_ast,
1110} ;
1211
@@ -61,11 +60,8 @@ pub fn find_builtin_derive(ident: &name::Name) -> Option<BuiltinDeriveExpander>
6160
6261struct BasicAdtInfo {
6362 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 > > ,
6965}
7066
7167fn parse_adt ( tt : & tt:: Subtree ) -> Result < BasicAdtInfo , ExpandError > {
@@ -79,34 +75,17 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
7975 ExpandError :: Other ( "no item found" . into ( ) )
8076 } ) ?;
8177 let node = item. syntax ( ) ;
82- let ( name, params, fields ) = match_ast ! {
78+ let ( name, params) = match_ast ! {
8379 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( ) ) ,
8983 _ => {
9084 debug!( "unexpected node is {:?}" , node) ;
9185 return Err ( ExpandError :: Other ( "expected struct, enum or union" . into( ) ) )
9286 } ,
9387 }
9488 } ;
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 < _ > > ( ) ;
11089 let name = name. ok_or_else ( || {
11190 debug ! ( "parsed item has no name" ) ;
11291 ExpandError :: Other ( "missing name" . into ( ) )
@@ -118,46 +97,35 @@ fn parse_adt(tt: &tt::Subtree) -> Result<BasicAdtInfo, ExpandError> {
11897 . into_iter ( )
11998 . flat_map ( |param_list| param_list. type_or_const_params ( ) )
12099 . 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 {
132101 let ty = param
133102 . ty ( )
134103 . map ( |ty| mbe:: syntax_node_to_token_tree ( ty. syntax ( ) ) . 0 )
135104 . unwrap_or_else ( tt:: Subtree :: empty) ;
136105 Some ( ty)
137106 } else {
138107 None
139- } ;
140- ( name, ty, bounds)
108+ }
141109 } )
142110 . collect ( ) ;
143- Ok ( BasicAdtInfo { name : name_token, param_types, field_types } )
111+ Ok ( BasicAdtInfo { name : name_token, param_types } )
144112}
145113
146114fn expand_simple_derive ( tt : & tt:: Subtree , trait_path : tt:: Subtree ) -> ExpandResult < tt:: Subtree > {
147115 let info = match parse_adt ( tt) {
148116 Ok ( info) => info,
149117 Err ( e) => return ExpandResult :: with_err ( tt:: Subtree :: empty ( ) , e) ,
150118 } ;
151- let mut where_block = vec ! [ ] ;
152119 let ( params, args) : ( Vec < _ > , Vec < _ > ) = info
153120 . param_types
154121 . 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+ } ) ;
156128 let ident_ = ident. clone ( ) ;
157- if let Some ( b) = bound {
158- let ident = ident. clone ( ) ;
159- where_block. push ( quote ! { #ident : #b , } ) ;
160- }
161129 if let Some ( ty) = param_ty {
162130 ( quote ! { const #ident : #ty , } , quote ! { #ident_ , } )
163131 } else {
@@ -166,16 +134,9 @@ fn expand_simple_derive(tt: &tt::Subtree, trait_path: tt::Subtree) -> ExpandResu
166134 }
167135 } )
168136 . 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-
176137 let name = info. name ;
177138 let expanded = quote ! {
178- impl < ##params > #trait_path for #name < ##args > where ##where_block { }
139+ impl < ##params > #trait_path for #name < ##args > { }
179140 } ;
180141 ExpandResult :: ok ( expanded)
181142}
0 commit comments