@@ -44,6 +44,7 @@ mod diagnostic;
4444mod escape;
4545mod to_tokens;
4646
47+ use core:: convert:: From ;
4748use core:: ops:: BitOr ;
4849use std:: ffi:: CStr ;
4950use std:: ops:: { Range , RangeBounds } ;
@@ -53,8 +54,6 @@ use std::{error, fmt};
5354
5455#[ unstable( feature = "proc_macro_diagnostic" , issue = "54140" ) ]
5556pub use diagnostic:: { Diagnostic , Level , MultiSpan } ;
56- #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
57- pub use rustc_literal_escaper:: EscapeError ;
5857use rustc_literal_escaper:: {
5958 MixedUnit , unescape_byte, unescape_byte_str, unescape_c_str, unescape_char, unescape_str,
6059} ;
@@ -64,6 +63,135 @@ pub use to_tokens::ToTokens;
6463use crate :: bridge:: client:: Methods as BridgeMethods ;
6564use crate :: escape:: { EscapeOptions , escape_bytes} ;
6665
66+ /// Mostly relating to malformed escape sequences, but also a few other problems.
67+ #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
68+ #[ derive( Debug , PartialEq , Eq ) ]
69+ #[ non_exhaustive]
70+ pub enum EscapeError {
71+ /// Expected 1 char, but 0 were found.
72+ ZeroChars ,
73+ /// Expected 1 char, but more than 1 were found.
74+ MoreThanOneChar ,
75+
76+ /// Escaped '\' character without continuation.
77+ LoneSlash ,
78+ /// Invalid escape character (e.g. '\z').
79+ InvalidEscape ,
80+ /// Raw '\r' encountered.
81+ BareCarriageReturn ,
82+ /// Raw '\r' encountered in raw string.
83+ BareCarriageReturnInRawString ,
84+ /// Unescaped character that was expected to be escaped (e.g. raw '\t').
85+ EscapeOnlyChar ,
86+
87+ /// Numeric character escape is too short (e.g. '\x1').
88+ TooShortHexEscape ,
89+ /// Invalid character in numeric escape (e.g. '\xz')
90+ InvalidCharInHexEscape ,
91+ /// Character code in numeric escape is non-ascii (e.g. '\xFF').
92+ OutOfRangeHexEscape ,
93+
94+ /// '\u' not followed by '{'.
95+ NoBraceInUnicodeEscape ,
96+ /// Non-hexadecimal value in '\u{..}'.
97+ InvalidCharInUnicodeEscape ,
98+ /// '\u{}'
99+ EmptyUnicodeEscape ,
100+ /// No closing brace in '\u{..}', e.g. '\u{12'.
101+ UnclosedUnicodeEscape ,
102+ /// '\u{_12}'
103+ LeadingUnderscoreUnicodeEscape ,
104+ /// More than 6 characters in '\u{..}', e.g. '\u{10FFFF_FF}'
105+ OverlongUnicodeEscape ,
106+ /// Invalid in-bound unicode character code, e.g. '\u{DFFF}'.
107+ LoneSurrogateUnicodeEscape ,
108+ /// Out of bounds unicode character code, e.g. '\u{FFFFFF}'.
109+ OutOfRangeUnicodeEscape ,
110+
111+ /// Unicode escape code in byte literal.
112+ UnicodeEscapeInByte ,
113+ /// Non-ascii character in byte literal, byte string literal, or raw byte string literal.
114+ NonAsciiCharInByte ,
115+
116+ /// `\0` in a C string literal.
117+ NulInCStr ,
118+
119+ /// After a line ending with '\', the next line contains whitespace
120+ /// characters that are not skipped.
121+ UnskippedWhitespaceWarning ,
122+
123+ /// After a line ending with '\', multiple lines are skipped.
124+ MultipleSkippedLinesWarning ,
125+ }
126+
127+ #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
128+ #[ doc( hidden) ]
129+ impl From < rustc_literal_escaper:: EscapeError > for EscapeError {
130+ fn from ( value : rustc_literal_escaper:: EscapeError ) -> Self {
131+ use rustc_literal_escaper:: EscapeError as EE ;
132+
133+ match value {
134+ EE :: ZeroChars => Self :: ZeroChars ,
135+ EE :: MoreThanOneChar => Self :: MoreThanOneChar ,
136+ EE :: LoneSlash => Self :: LoneSlash ,
137+ EE :: InvalidEscape => Self :: InvalidEscape ,
138+ EE :: BareCarriageReturn => Self :: BareCarriageReturn ,
139+ EE :: BareCarriageReturnInRawString => Self :: BareCarriageReturnInRawString ,
140+ EE :: EscapeOnlyChar => Self :: EscapeOnlyChar ,
141+ EE :: TooShortHexEscape => Self :: TooShortHexEscape ,
142+ EE :: InvalidCharInHexEscape => Self :: InvalidCharInHexEscape ,
143+ EE :: OutOfRangeHexEscape => Self :: OutOfRangeHexEscape ,
144+ EE :: NoBraceInUnicodeEscape => Self :: NoBraceInUnicodeEscape ,
145+ EE :: InvalidCharInUnicodeEscape => Self :: InvalidCharInUnicodeEscape ,
146+ EE :: EmptyUnicodeEscape => Self :: EmptyUnicodeEscape ,
147+ EE :: UnclosedUnicodeEscape => Self :: UnclosedUnicodeEscape ,
148+ EE :: LeadingUnderscoreUnicodeEscape => Self :: LeadingUnderscoreUnicodeEscape ,
149+ EE :: OverlongUnicodeEscape => Self :: OverlongUnicodeEscape ,
150+ EE :: LoneSurrogateUnicodeEscape => Self :: LoneSurrogateUnicodeEscape ,
151+ EE :: OutOfRangeUnicodeEscape => Self :: OutOfRangeUnicodeEscape ,
152+ EE :: UnicodeEscapeInByte => Self :: UnicodeEscapeInByte ,
153+ EE :: NonAsciiCharInByte => Self :: NonAsciiCharInByte ,
154+ EE :: NulInCStr => Self :: NulInCStr ,
155+ EE :: UnskippedWhitespaceWarning => Self :: UnskippedWhitespaceWarning ,
156+ EE :: MultipleSkippedLinesWarning => Self :: MultipleSkippedLinesWarning ,
157+ }
158+ }
159+ }
160+
161+ #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
162+ impl error:: Error for EscapeError { }
163+
164+ #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
165+ impl fmt:: Display for EscapeError {
166+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
167+ f. write_str ( match self {
168+ Self :: ZeroChars => "zero chars" ,
169+ Self :: MoreThanOneChar => "more than one char" ,
170+ Self :: LoneSlash => "lone slash" ,
171+ Self :: InvalidEscape => "invalid escape" ,
172+ Self :: BareCarriageReturn => "bare carriage return" ,
173+ Self :: BareCarriageReturnInRawString => "bare carriage return in raw string" ,
174+ Self :: EscapeOnlyChar => "escape only char" ,
175+ Self :: TooShortHexEscape => "too short hex escape" ,
176+ Self :: InvalidCharInHexEscape => "invalid char in hex escape" ,
177+ Self :: OutOfRangeHexEscape => "out of range hex escape" ,
178+ Self :: NoBraceInUnicodeEscape => "no brace in unicode escape" ,
179+ Self :: InvalidCharInUnicodeEscape => "invalid char in unicode escape" ,
180+ Self :: EmptyUnicodeEscape => "empty unicode escape" ,
181+ Self :: UnclosedUnicodeEscape => "unclosed unicode escape" ,
182+ Self :: LeadingUnderscoreUnicodeEscape => "leading underscore unicode escape" ,
183+ Self :: OverlongUnicodeEscape => "overlong unicode escape" ,
184+ Self :: LoneSurrogateUnicodeEscape => "lone surrogate unicode escape" ,
185+ Self :: OutOfRangeUnicodeEscape => "out of range unicode escape" ,
186+ Self :: UnicodeEscapeInByte => "unicode escape in byte" ,
187+ Self :: NonAsciiCharInByte => "non ascii char in byte" ,
188+ Self :: NulInCStr => "nul in CStr" ,
189+ Self :: UnskippedWhitespaceWarning => "unskipped whitespace warning" ,
190+ Self :: MultipleSkippedLinesWarning => "multiple skipped lines warning" ,
191+ } )
192+ }
193+ }
194+
67195/// Errors returned when trying to retrieve a literal unescaped value.
68196#[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
69197#[ derive( Debug , PartialEq , Eq ) ]
@@ -1461,9 +1589,8 @@ impl Literal {
14611589 #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
14621590 pub fn byte_character_value ( & self ) -> Result < u8 , ConversionErrorKind > {
14631591 self . 0 . symbol . with ( |symbol| match self . 0 . kind {
1464- bridge:: LitKind :: Char => {
1465- unescape_byte ( symbol) . map_err ( ConversionErrorKind :: FailedToUnescape )
1466- }
1592+ bridge:: LitKind :: Char => unescape_byte ( symbol)
1593+ . map_err ( |err| ConversionErrorKind :: FailedToUnescape ( err. into ( ) ) ) ,
14671594 _ => Err ( ConversionErrorKind :: InvalidLiteralKind ) ,
14681595 } )
14691596 }
@@ -1472,9 +1599,8 @@ impl Literal {
14721599 #[ unstable( feature = "proc_macro_value" , issue = "136652" ) ]
14731600 pub fn character_value ( & self ) -> Result < char , ConversionErrorKind > {
14741601 self . 0 . symbol . with ( |symbol| match self . 0 . kind {
1475- bridge:: LitKind :: Char => {
1476- unescape_char ( symbol) . map_err ( ConversionErrorKind :: FailedToUnescape )
1477- }
1602+ bridge:: LitKind :: Char => unescape_char ( symbol)
1603+ . map_err ( |err| ConversionErrorKind :: FailedToUnescape ( err. into ( ) ) ) ,
14781604 _ => Err ( ConversionErrorKind :: InvalidLiteralKind ) ,
14791605 } )
14801606 }
@@ -1497,7 +1623,7 @@ impl Literal {
14971623 Ok ( c) => buf. push ( c) ,
14981624 Err ( err) => {
14991625 if err. is_fatal ( ) {
1500- error = Some ( ConversionErrorKind :: FailedToUnescape ( err) ) ;
1626+ error = Some ( ConversionErrorKind :: FailedToUnescape ( err. into ( ) ) ) ;
15011627 }
15021628 }
15031629 } ,
@@ -1528,7 +1654,7 @@ impl Literal {
15281654 Ok ( MixedUnit :: HighByte ( b) ) => buf. push ( b. get ( ) ) ,
15291655 Err ( err) => {
15301656 if err. is_fatal ( ) {
1531- error = Some ( ConversionErrorKind :: FailedToUnescape ( err) ) ;
1657+ error = Some ( ConversionErrorKind :: FailedToUnescape ( err. into ( ) ) ) ;
15321658 }
15331659 }
15341660 } ) ;
@@ -1564,7 +1690,7 @@ impl Literal {
15641690 Ok ( b) => buf. push ( b) ,
15651691 Err ( err) => {
15661692 if err. is_fatal ( ) {
1567- error = Some ( ConversionErrorKind :: FailedToUnescape ( err) ) ;
1693+ error = Some ( ConversionErrorKind :: FailedToUnescape ( err. into ( ) ) ) ;
15681694 }
15691695 }
15701696 } ) ;
0 commit comments