@@ -6,7 +6,7 @@ use std::{
66} ;
77
88use rustc_lexer:: unescape:: {
9- unescape_byte, unescape_char, unescape_mixed, unescape_unicode, MixedUnit , Mode ,
9+ unescape_byte, unescape_char, unescape_mixed, unescape_unicode, EscapeError , MixedUnit , Mode ,
1010} ;
1111
1212use crate :: {
@@ -180,10 +180,7 @@ pub trait IsString: AstToken {
180180 fn close_quote_text_range ( & self ) -> Option < TextRange > {
181181 self . quote_offsets ( ) . map ( |it| it. quotes . 1 )
182182 }
183- fn escaped_char_ranges (
184- & self ,
185- cb : & mut dyn FnMut ( TextRange , Result < char , rustc_lexer:: unescape:: EscapeError > ) ,
186- ) {
183+ fn escaped_char_ranges ( & self , cb : & mut dyn FnMut ( TextRange , Result < char , EscapeError > ) ) {
187184 let text_range_no_quotes = match self . text_range_between_quotes ( ) {
188185 Some ( it) => it,
189186 None => return ,
@@ -212,20 +209,17 @@ impl IsString for ast::String {
212209}
213210
214211impl ast:: String {
215- pub fn value ( & self ) -> Option < Cow < ' _ , str > > {
212+ pub fn value ( & self ) -> Result < Cow < ' _ , str > , EscapeError > {
213+ let text = self . text ( ) ;
214+ let text_range = self . text_range_between_quotes ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
215+ let text = & text[ text_range - self . syntax ( ) . text_range ( ) . start ( ) ] ;
216216 if self . is_raw ( ) {
217- let text = self . text ( ) ;
218- let text =
219- & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
220- return Some ( Cow :: Borrowed ( text) ) ;
217+ return Ok ( Cow :: Borrowed ( text) ) ;
221218 }
222219
223- let text = self . text ( ) ;
224- let text = & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
225-
226220 let mut buf = String :: new ( ) ;
227221 let mut prev_end = 0 ;
228- let mut has_error = false ;
222+ let mut has_error = None ;
229223 unescape_unicode ( text, Self :: MODE , & mut |char_range, unescaped_char| match (
230224 unescaped_char,
231225 buf. capacity ( ) == 0 ,
@@ -239,13 +233,13 @@ impl ast::String {
239233 buf. push_str ( & text[ ..prev_end] ) ;
240234 buf. push ( c) ;
241235 }
242- ( Err ( _ ) , _) => has_error = true ,
236+ ( Err ( e ) , _) => has_error = Some ( e ) ,
243237 } ) ;
244238
245239 match ( has_error, buf. capacity ( ) == 0 ) {
246- ( true , _) => None ,
247- ( false , true ) => Some ( Cow :: Borrowed ( text) ) ,
248- ( false , false ) => Some ( Cow :: Owned ( buf) ) ,
240+ ( Some ( e ) , _) => Err ( e ) ,
241+ ( None , true ) => Ok ( Cow :: Borrowed ( text) ) ,
242+ ( None , false ) => Ok ( Cow :: Owned ( buf) ) ,
249243 }
250244 }
251245}
@@ -256,20 +250,17 @@ impl IsString for ast::ByteString {
256250}
257251
258252impl ast:: ByteString {
259- pub fn value ( & self ) -> Option < Cow < ' _ , [ u8 ] > > {
253+ pub fn value ( & self ) -> Result < Cow < ' _ , [ u8 ] > , EscapeError > {
254+ let text = self . text ( ) ;
255+ let text_range = self . text_range_between_quotes ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
256+ let text = & text[ text_range - self . syntax ( ) . text_range ( ) . start ( ) ] ;
260257 if self . is_raw ( ) {
261- let text = self . text ( ) ;
262- let text =
263- & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
264- return Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
258+ return Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
265259 }
266260
267- let text = self . text ( ) ;
268- let text = & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
269-
270261 let mut buf: Vec < u8 > = Vec :: new ( ) ;
271262 let mut prev_end = 0 ;
272- let mut has_error = false ;
263+ let mut has_error = None ;
273264 unescape_unicode ( text, Self :: MODE , & mut |char_range, unescaped_char| match (
274265 unescaped_char,
275266 buf. capacity ( ) == 0 ,
@@ -283,13 +274,13 @@ impl ast::ByteString {
283274 buf. extend_from_slice ( text[ ..prev_end] . as_bytes ( ) ) ;
284275 buf. push ( c as u8 ) ;
285276 }
286- ( Err ( _ ) , _) => has_error = true ,
277+ ( Err ( e ) , _) => has_error = Some ( e ) ,
287278 } ) ;
288279
289280 match ( has_error, buf. capacity ( ) == 0 ) {
290- ( true , _) => None ,
291- ( false , true ) => Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
292- ( false , false ) => Some ( Cow :: Owned ( buf) ) ,
281+ ( Some ( e ) , _) => Err ( e ) ,
282+ ( None , true ) => Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
283+ ( None , false ) => Ok ( Cow :: Owned ( buf) ) ,
293284 }
294285 }
295286}
@@ -298,10 +289,7 @@ impl IsString for ast::CString {
298289 const RAW_PREFIX : & ' static str = "cr" ;
299290 const MODE : Mode = Mode :: CStr ;
300291
301- fn escaped_char_ranges (
302- & self ,
303- cb : & mut dyn FnMut ( TextRange , Result < char , rustc_lexer:: unescape:: EscapeError > ) ,
304- ) {
292+ fn escaped_char_ranges ( & self , cb : & mut dyn FnMut ( TextRange , Result < char , EscapeError > ) ) {
305293 let text_range_no_quotes = match self . text_range_between_quotes ( ) {
306294 Some ( it) => it,
307295 None => return ,
@@ -322,20 +310,17 @@ impl IsString for ast::CString {
322310}
323311
324312impl ast:: CString {
325- pub fn value ( & self ) -> Option < Cow < ' _ , [ u8 ] > > {
313+ pub fn value ( & self ) -> Result < Cow < ' _ , [ u8 ] > , EscapeError > {
314+ let text = self . text ( ) ;
315+ let text_range = self . text_range_between_quotes ( ) . ok_or ( EscapeError :: LoneSlash ) ?;
316+ let text = & text[ text_range - self . syntax ( ) . text_range ( ) . start ( ) ] ;
326317 if self . is_raw ( ) {
327- let text = self . text ( ) ;
328- let text =
329- & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
330- return Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
318+ return Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ;
331319 }
332320
333- let text = self . text ( ) ;
334- let text = & text[ self . text_range_between_quotes ( ) ? - self . syntax ( ) . text_range ( ) . start ( ) ] ;
335-
336321 let mut buf = Vec :: new ( ) ;
337322 let mut prev_end = 0 ;
338- let mut has_error = false ;
323+ let mut has_error = None ;
339324 let extend_unit = |buf : & mut Vec < u8 > , unit : MixedUnit | match unit {
340325 MixedUnit :: Char ( c) => buf. extend ( c. encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) ) ,
341326 MixedUnit :: HighByte ( b) => buf. push ( b) ,
@@ -353,13 +338,13 @@ impl ast::CString {
353338 buf. extend ( text[ ..prev_end] . as_bytes ( ) ) ;
354339 extend_unit ( & mut buf, u) ;
355340 }
356- ( Err ( _ ) , _) => has_error = true ,
341+ ( Err ( e ) , _) => has_error = Some ( e ) ,
357342 } ) ;
358343
359344 match ( has_error, buf. capacity ( ) == 0 ) {
360- ( true , _) => None ,
361- ( false , true ) => Some ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
362- ( false , false ) => Some ( Cow :: Owned ( buf) ) ,
345+ ( Some ( e ) , _) => Err ( e ) ,
346+ ( None , true ) => Ok ( Cow :: Borrowed ( text. as_bytes ( ) ) ) ,
347+ ( None , false ) => Ok ( Cow :: Owned ( buf) ) ,
363348 }
364349 }
365350}
@@ -478,34 +463,34 @@ impl Radix {
478463}
479464
480465impl ast:: Char {
481- pub fn value ( & self ) -> Option < char > {
466+ pub fn value ( & self ) -> Result < char , EscapeError > {
482467 let mut text = self . text ( ) ;
483468 if text. starts_with ( '\'' ) {
484469 text = & text[ 1 ..] ;
485470 } else {
486- return None ;
471+ return Err ( EscapeError :: ZeroChars ) ;
487472 }
488473 if text. ends_with ( '\'' ) {
489474 text = & text[ 0 ..text. len ( ) - 1 ] ;
490475 }
491476
492- unescape_char ( text) . ok ( )
477+ unescape_char ( text)
493478 }
494479}
495480
496481impl ast:: Byte {
497- pub fn value ( & self ) -> Option < u8 > {
482+ pub fn value ( & self ) -> Result < u8 , EscapeError > {
498483 let mut text = self . text ( ) ;
499484 if text. starts_with ( "b\' " ) {
500485 text = & text[ 2 ..] ;
501486 } else {
502- return None ;
487+ return Err ( EscapeError :: ZeroChars ) ;
503488 }
504489 if text. ends_with ( '\'' ) {
505490 text = & text[ 0 ..text. len ( ) - 1 ] ;
506491 }
507492
508- unescape_byte ( text) . ok ( )
493+ unescape_byte ( text)
509494 }
510495}
511496
@@ -559,7 +544,10 @@ mod tests {
559544
560545 fn check_string_value < ' a > ( lit : & str , expected : impl Into < Option < & ' a str > > ) {
561546 assert_eq ! (
562- ast:: String { syntax: make:: tokens:: literal( & format!( "\" {lit}\" " ) ) } . value( ) . as_deref( ) ,
547+ ast:: String { syntax: make:: tokens:: literal( & format!( "\" {lit}\" " ) ) }
548+ . value( )
549+ . as_deref( )
550+ . ok( ) ,
563551 expected. into( )
564552 ) ;
565553 }
@@ -584,7 +572,8 @@ bcde", "abcde",
584572 assert_eq ! (
585573 ast:: ByteString { syntax: make:: tokens:: literal( & format!( "b\" {lit}\" " ) ) }
586574 . value( )
587- . as_deref( ) ,
575+ . as_deref( )
576+ . ok( ) ,
588577 expected. into( ) . map( |value| & value[ ..] )
589578 ) ;
590579 }
0 commit comments