@@ -15,7 +15,9 @@ use core::mem::ManuallyDrop;
15
15
use core:: ops:: Range ;
16
16
use core:: ops:: RangeBounds ;
17
17
use core:: ptr;
18
- use core:: str:: { self , FromStr } ;
18
+ use core:: str;
19
+ #[ cfg( feature = "proc-macro" ) ]
20
+ use core:: str:: FromStr ;
19
21
use std:: ffi:: CStr ;
20
22
#[ cfg( procmacro2_semver_exempt) ]
21
23
use std:: path:: PathBuf ;
@@ -63,6 +65,24 @@ impl TokenStream {
63
65
}
64
66
}
65
67
68
+ pub ( crate ) fn from_str_checked ( src : & str ) -> Result < Self , LexError > {
69
+ // Create a dummy file & add it to the source map
70
+ let mut cursor = get_cursor ( src) ;
71
+
72
+ // Strip a byte order mark if present
73
+ const BYTE_ORDER_MARK : & str = "\u{feff} " ;
74
+ if cursor. starts_with ( BYTE_ORDER_MARK ) {
75
+ cursor = cursor. advance ( BYTE_ORDER_MARK . len ( ) ) ;
76
+ }
77
+
78
+ parse:: token_stream ( cursor)
79
+ }
80
+
81
+ #[ cfg( feature = "proc-macro" ) ]
82
+ pub ( crate ) fn from_str_unchecked ( src : & str ) -> Self {
83
+ Self :: from_str_checked ( src) . unwrap ( )
84
+ }
85
+
66
86
pub ( crate ) fn is_empty ( & self ) -> bool {
67
87
self . inner . len ( ) == 0
68
88
}
@@ -170,23 +190,6 @@ fn get_cursor(src: &str) -> Cursor {
170
190
Cursor { rest : src }
171
191
}
172
192
173
- impl FromStr for TokenStream {
174
- type Err = LexError ;
175
-
176
- fn from_str ( src : & str ) -> Result < TokenStream , LexError > {
177
- // Create a dummy file & add it to the source map
178
- let mut cursor = get_cursor ( src) ;
179
-
180
- // Strip a byte order mark if present
181
- const BYTE_ORDER_MARK : & str = "\u{feff} " ;
182
- if cursor. starts_with ( BYTE_ORDER_MARK ) {
183
- cursor = cursor. advance ( BYTE_ORDER_MARK . len ( ) ) ;
184
- }
185
-
186
- parse:: token_stream ( cursor)
187
- }
188
- }
189
-
190
193
impl Display for LexError {
191
194
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
192
195
f. write_str ( "cannot parse string into token stream" )
@@ -226,15 +229,14 @@ impl Debug for TokenStream {
226
229
#[ cfg( feature = "proc-macro" ) ]
227
230
impl From < proc_macro:: TokenStream > for TokenStream {
228
231
fn from ( inner : proc_macro:: TokenStream ) -> Self {
229
- TokenStream :: from_str ( & inner. to_string ( ) ) . expect ( "compiler token stream parse failed" )
232
+ TokenStream :: from_str_unchecked ( & inner. to_string ( ) )
230
233
}
231
234
}
232
235
233
236
#[ cfg( feature = "proc-macro" ) ]
234
237
impl From < TokenStream > for proc_macro:: TokenStream {
235
238
fn from ( inner : TokenStream ) -> Self {
236
- proc_macro:: TokenStream :: from_str ( & inner. to_string ( ) )
237
- . expect ( "failed to parse to compiler tokens" )
239
+ proc_macro:: TokenStream :: from_str_unchecked ( & inner. to_string ( ) )
238
240
}
239
241
}
240
242
@@ -950,6 +952,36 @@ impl Literal {
950
952
}
951
953
}
952
954
955
+ pub ( crate ) fn from_str_checked ( repr : & str ) -> Result < Self , LexError > {
956
+ let mut cursor = get_cursor ( repr) ;
957
+ #[ cfg( span_locations) ]
958
+ let lo = cursor. off ;
959
+
960
+ let negative = cursor. starts_with_char ( '-' ) ;
961
+ if negative {
962
+ cursor = cursor. advance ( 1 ) ;
963
+ if !cursor. starts_with_fn ( |ch| ch. is_ascii_digit ( ) ) {
964
+ return Err ( LexError :: call_site ( ) ) ;
965
+ }
966
+ }
967
+
968
+ if let Ok ( ( rest, mut literal) ) = parse:: literal ( cursor) {
969
+ if rest. is_empty ( ) {
970
+ if negative {
971
+ literal. repr . insert ( 0 , '-' ) ;
972
+ }
973
+ literal. span = Span {
974
+ #[ cfg( span_locations) ]
975
+ lo,
976
+ #[ cfg( span_locations) ]
977
+ hi : rest. off ,
978
+ } ;
979
+ return Ok ( literal) ;
980
+ }
981
+ }
982
+ Err ( LexError :: call_site ( ) )
983
+ }
984
+
953
985
pub ( crate ) unsafe fn from_str_unchecked ( repr : & str ) -> Self {
954
986
Literal :: _new ( repr. to_owned ( ) )
955
987
}
@@ -1147,40 +1179,6 @@ impl Literal {
1147
1179
}
1148
1180
}
1149
1181
1150
- impl FromStr for Literal {
1151
- type Err = LexError ;
1152
-
1153
- fn from_str ( repr : & str ) -> Result < Self , Self :: Err > {
1154
- let mut cursor = get_cursor ( repr) ;
1155
- #[ cfg( span_locations) ]
1156
- let lo = cursor. off ;
1157
-
1158
- let negative = cursor. starts_with_char ( '-' ) ;
1159
- if negative {
1160
- cursor = cursor. advance ( 1 ) ;
1161
- if !cursor. starts_with_fn ( |ch| ch. is_ascii_digit ( ) ) {
1162
- return Err ( LexError :: call_site ( ) ) ;
1163
- }
1164
- }
1165
-
1166
- if let Ok ( ( rest, mut literal) ) = parse:: literal ( cursor) {
1167
- if rest. is_empty ( ) {
1168
- if negative {
1169
- literal. repr . insert ( 0 , '-' ) ;
1170
- }
1171
- literal. span = Span {
1172
- #[ cfg( span_locations) ]
1173
- lo,
1174
- #[ cfg( span_locations) ]
1175
- hi : rest. off ,
1176
- } ;
1177
- return Ok ( literal) ;
1178
- }
1179
- }
1180
- Err ( LexError :: call_site ( ) )
1181
- }
1182
- }
1183
-
1184
1182
impl Display for Literal {
1185
1183
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
1186
1184
Display :: fmt ( & self . repr , f)
@@ -1219,3 +1217,21 @@ fn escape_utf8(string: &str, repr: &mut String) {
1219
1217
}
1220
1218
}
1221
1219
}
1220
+
1221
+ #[ cfg( feature = "proc-macro" ) ]
1222
+ pub ( crate ) trait FromStr2 : FromStr < Err = proc_macro:: LexError > {
1223
+ #[ cfg( wrap_proc_macro) ]
1224
+ fn from_str_checked ( src : & str ) -> Result < Self , Self :: Err > {
1225
+ Self :: from_str ( src)
1226
+ }
1227
+
1228
+ fn from_str_unchecked ( src : & str ) -> Self {
1229
+ Self :: from_str ( src) . unwrap ( )
1230
+ }
1231
+ }
1232
+
1233
+ #[ cfg( feature = "proc-macro" ) ]
1234
+ impl FromStr2 for proc_macro:: TokenStream { }
1235
+
1236
+ #[ cfg( feature = "proc-macro" ) ]
1237
+ impl FromStr2 for proc_macro:: Literal { }
0 commit comments