@@ -15,7 +15,9 @@ use core::mem::ManuallyDrop;
1515use core:: ops:: Range ;
1616use core:: ops:: RangeBounds ;
1717use core:: ptr;
18- use core:: str:: { self , FromStr } ;
18+ use core:: str;
19+ #[ cfg( feature = "proc-macro" ) ]
20+ use core:: str:: FromStr ;
1921use std:: ffi:: CStr ;
2022#[ cfg( procmacro2_semver_exempt) ]
2123use std:: path:: PathBuf ;
@@ -63,6 +65,24 @@ impl TokenStream {
6365 }
6466 }
6567
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+
6686 pub ( crate ) fn is_empty ( & self ) -> bool {
6787 self . inner . len ( ) == 0
6888 }
@@ -170,23 +190,6 @@ fn get_cursor(src: &str) -> Cursor {
170190 Cursor { rest : src }
171191}
172192
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-
190193impl Display for LexError {
191194 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
192195 f. write_str ( "cannot parse string into token stream" )
@@ -226,15 +229,14 @@ impl Debug for TokenStream {
226229#[ cfg( feature = "proc-macro" ) ]
227230impl From < proc_macro:: TokenStream > for TokenStream {
228231 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 ( ) )
230233 }
231234}
232235
233236#[ cfg( feature = "proc-macro" ) ]
234237impl From < TokenStream > for proc_macro:: TokenStream {
235238 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 ( ) )
238240 }
239241}
240242
@@ -950,6 +952,36 @@ impl Literal {
950952 }
951953 }
952954
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+
953985 pub ( crate ) unsafe fn from_str_unchecked ( repr : & str ) -> Self {
954986 Literal :: _new ( repr. to_owned ( ) )
955987 }
@@ -1147,40 +1179,6 @@ impl Literal {
11471179 }
11481180}
11491181
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-
11841182impl Display for Literal {
11851183 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
11861184 Display :: fmt ( & self . repr , f)
@@ -1219,3 +1217,21 @@ fn escape_utf8(string: &str, repr: &mut String) {
12191217 }
12201218 }
12211219}
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