88//! Keep in mind that `from_text` functions should be kept private. The public
99//! API should require to assemble every node piecewise. The trick of
1010//! `parse(format!())` we use internally is an implementation detail -- long
11- //! term, it will be replaced with direct tree manipulation.
11+ //! term, it will be replaced with `quote!`. Do not add more usages to `from_text` -
12+ //! use `quote!` instead.
1213
1314mod quote;
1415
@@ -120,7 +121,11 @@ pub fn name(name: &str) -> ast::Name {
120121}
121122pub fn name_ref ( name_ref : & str ) -> ast:: NameRef {
122123 let raw_escape = raw_ident_esc ( name_ref) ;
123- ast_from_text ( & format ! ( "fn f() {{ {raw_escape}{name_ref}; }}" ) )
124+ quote ! {
125+ NameRef {
126+ [ IDENT format!( "{raw_escape}{name_ref}" ) ]
127+ }
128+ }
124129}
125130fn raw_ident_esc ( ident : & str ) -> & ' static str {
126131 if is_raw_identifier ( ident, Edition :: CURRENT ) {
@@ -137,7 +142,11 @@ pub fn lifetime(text: &str) -> ast::Lifetime {
137142 tmp = format ! ( "'{text}" ) ;
138143 text = & tmp;
139144 }
140- ast_from_text ( & format ! ( "fn f<{text}>() {{ }}" ) )
145+ quote ! {
146+ Lifetime {
147+ [ LIFETIME_IDENT text]
148+ }
149+ }
141150}
142151
143152// FIXME: replace stringly-typed constructor with a family of typed ctors, a-la
@@ -177,63 +186,37 @@ pub fn ty_alias(
177186 where_clause : Option < ast:: WhereClause > ,
178187 assignment : Option < ( ast:: Type , Option < ast:: WhereClause > ) > ,
179188) -> ast:: TypeAlias {
180- let mut s = String :: new ( ) ;
181- s. push_str ( & format ! ( "type {ident}" ) ) ;
182-
183- if let Some ( list) = generic_param_list {
184- s. push_str ( & list. to_string ( ) ) ;
185- }
186-
187- if let Some ( list) = type_param_bounds {
188- s. push_str ( & format ! ( " : {list}" ) ) ;
189- }
190-
191- if let Some ( cl) = where_clause {
192- s. push_str ( & format ! ( " {cl}" ) ) ;
193- }
194-
195- if let Some ( exp) = assignment {
196- if let Some ( cl) = exp. 1 {
197- s. push_str ( & format ! ( " = {} {cl}" , exp. 0 ) ) ;
198- } else {
199- s. push_str ( & format ! ( " = {}" , exp. 0 ) ) ;
189+ let ( assignment_ty, assignment_where) = assignment. unzip ( ) ;
190+ let assignment_where = assignment_where. flatten ( ) ;
191+ quote ! {
192+ TypeAlias {
193+ [ type ] " "
194+ Name { [ IDENT ident] }
195+ #generic_param_list
196+ #( " " [ : ] " " #type_param_bounds) *
197+ #( " " #where_clause) *
198+ #( " " [ =] " " #assignment_ty) *
199+ #( " " #assignment_where) *
200+ [ ; ]
200201 }
201202 }
202-
203- s. push ( ';' ) ;
204- ast_from_text ( & s)
205203}
206204
207205pub fn ty_fn_ptr < I : Iterator < Item = Param > > (
208- for_lifetime_list : Option < ast:: GenericParamList > ,
209206 is_unsafe : bool ,
210207 abi : Option < ast:: Abi > ,
211- params : I ,
208+ mut params : I ,
212209 ret_type : Option < ast:: RetType > ,
213210) -> ast:: FnPtrType {
214- let mut s = String :: from ( "type __ = " ) ;
215-
216- if let Some ( list) = for_lifetime_list {
217- format_to ! ( s, "for{} " , list) ;
218- }
219-
220- if is_unsafe {
221- s. push_str ( "unsafe " ) ;
222- }
223-
224- if let Some ( abi) = abi {
225- format_to ! ( s, "{} " , abi)
226- }
227-
228- s. push_str ( "fn" ) ;
229-
230- format_to ! ( s, "({})" , params. map( |p| p. to_string( ) ) . join( ", " ) ) ;
231-
232- if let Some ( ret_type) = ret_type {
233- format_to ! ( s, " {}" , ret_type) ;
211+ let is_unsafe = is_unsafe. then_some ( ( ) ) ;
212+ let first_param = params. next ( ) ;
213+ quote ! {
214+ FnPtrType {
215+ #( #is_unsafe [ unsafe ] " " ) * #( #abi " " ) * [ fn ]
216+ [ '(' ] #first_param #( [ , ] " " #params) * [ ')' ]
217+ #( " " #ret_type) *
218+ }
234219 }
235-
236- ast_from_text ( & s)
237220}
238221
239222pub fn assoc_item_list ( ) -> ast:: AssocItemList {
0 commit comments