@@ -48,6 +48,9 @@ impl LitKind {
48
48
return Err ( LitError :: InvalidSuffix ) ;
49
49
}
50
50
51
+ // For byte/char/string literals, chars and escapes have already been
52
+ // checked in the lexer (in `cook_lexer_literal`). So we can assume all
53
+ // chars and escapes are valid here.
51
54
Ok ( match kind {
52
55
token:: Bool => {
53
56
assert ! ( symbol. is_bool_lit( ) ) ;
@@ -56,12 +59,12 @@ impl LitKind {
56
59
token:: Byte => {
57
60
return unescape_byte ( symbol. as_str ( ) )
58
61
. map ( LitKind :: Byte )
59
- . map_err ( |_| LitError :: LexerError ) ;
62
+ . map_err ( |_| panic ! ( "failed to unescape byte literal" ) ) ;
60
63
}
61
64
token:: Char => {
62
65
return unescape_char ( symbol. as_str ( ) )
63
66
. map ( LitKind :: Char )
64
- . map_err ( |_| LitError :: LexerError ) ;
67
+ . map_err ( |_| panic ! ( "failed to unescape char literal" ) ) ;
65
68
}
66
69
67
70
// There are some valid suffixes for integer and float literals,
@@ -77,113 +80,69 @@ impl LitKind {
77
80
let s = symbol. as_str ( ) ;
78
81
// Vanilla strings are so common we optimize for the common case where no chars
79
82
// requiring special behaviour are present.
80
- let symbol = if s. contains ( [ '\\' , '\r' ] ) {
83
+ let symbol = if s. contains ( '\\' ) {
81
84
let mut buf = String :: with_capacity ( s. len ( ) ) ;
82
- let mut error = Ok ( ( ) ) ;
83
85
// Force-inlining here is aggressive but the closure is
84
- // called on every char in the string, so it can be
85
- // hot in programs with many long strings.
86
+ // called on every char in the string, so it can be hot in
87
+ // programs with many long strings containing escapes .
86
88
unescape_literal (
87
89
s,
88
90
Mode :: Str ,
89
91
& mut #[ inline ( always) ]
90
- |_, unescaped_char | match unescaped_char {
92
+ |_, c | match c {
91
93
Ok ( c) => buf. push ( c) ,
92
94
Err ( err) => {
93
- if err. is_fatal ( ) {
94
- error = Err ( LitError :: LexerError ) ;
95
- }
95
+ assert ! ( !err. is_fatal( ) , "failed to unescape string literal" )
96
96
}
97
97
} ,
98
98
) ;
99
- error?;
100
99
Symbol :: intern ( & buf)
101
100
} else {
102
101
symbol
103
102
} ;
104
103
LitKind :: Str ( symbol, ast:: StrStyle :: Cooked )
105
104
}
106
105
token:: StrRaw ( n) => {
107
- // Raw strings have no escapes, so we only need to check for invalid chars, and we
108
- // can reuse the symbol on success.
109
- let mut error = Ok ( ( ) ) ;
110
- unescape_literal ( symbol. as_str ( ) , Mode :: RawStr , & mut |_, unescaped_char| {
111
- match unescaped_char {
112
- Ok ( _) => { }
113
- Err ( err) => {
114
- if err. is_fatal ( ) {
115
- error = Err ( LitError :: LexerError ) ;
116
- }
117
- }
118
- }
119
- } ) ;
120
- error?;
106
+ // Raw strings have no escapes so no work is needed here.
121
107
LitKind :: Str ( symbol, ast:: StrStyle :: Raw ( n) )
122
108
}
123
109
token:: ByteStr => {
124
110
let s = symbol. as_str ( ) ;
125
111
let mut buf = Vec :: with_capacity ( s. len ( ) ) ;
126
- let mut error = Ok ( ( ) ) ;
127
112
unescape_literal ( s, Mode :: ByteStr , & mut |_, c| match c {
128
113
Ok ( c) => buf. push ( byte_from_char ( c) ) ,
129
114
Err ( err) => {
130
- if err. is_fatal ( ) {
131
- error = Err ( LitError :: LexerError ) ;
132
- }
115
+ assert ! ( !err. is_fatal( ) , "failed to unescape string literal" )
133
116
}
134
117
} ) ;
135
- error?;
136
118
LitKind :: ByteStr ( buf. into ( ) , StrStyle :: Cooked )
137
119
}
138
120
token:: ByteStrRaw ( n) => {
139
- // Raw strings have no escapes, so we only need to check for invalid chars, and we
140
- // can convert the symbol directly to a `Lrc<u8>` on success.
141
- let s = symbol. as_str ( ) ;
142
- let mut error = Ok ( ( ) ) ;
143
- unescape_literal ( s, Mode :: RawByteStr , & mut |_, c| match c {
144
- Ok ( _) => { }
145
- Err ( err) => {
146
- if err. is_fatal ( ) {
147
- error = Err ( LitError :: LexerError ) ;
148
- }
149
- }
150
- } ) ;
151
- LitKind :: ByteStr ( s. to_owned ( ) . into_bytes ( ) . into ( ) , StrStyle :: Raw ( n) )
121
+ // Raw strings have no escapes so we can convert the symbol
122
+ // directly to a `Lrc<u8>`.
123
+ let buf = symbol. as_str ( ) . to_owned ( ) . into_bytes ( ) ;
124
+ LitKind :: ByteStr ( buf. into ( ) , StrStyle :: Raw ( n) )
152
125
}
153
126
token:: CStr => {
154
127
let s = symbol. as_str ( ) ;
155
128
let mut buf = Vec :: with_capacity ( s. len ( ) ) ;
156
- let mut error = Ok ( ( ) ) ;
157
129
unescape_c_string ( s, Mode :: CStr , & mut |_span, c| match c {
158
130
Ok ( CStrUnit :: Byte ( b) ) => buf. push ( b) ,
159
131
Ok ( CStrUnit :: Char ( c) ) => {
160
132
buf. extend_from_slice ( c. encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) )
161
133
}
162
134
Err ( err) => {
163
- if err. is_fatal ( ) {
164
- error = Err ( LitError :: LexerError ) ;
165
- }
135
+ assert ! ( !err. is_fatal( ) , "failed to unescape C string literal" )
166
136
}
167
137
} ) ;
168
- error?;
169
138
buf. push ( 0 ) ;
170
139
LitKind :: CStr ( buf. into ( ) , StrStyle :: Cooked )
171
140
}
172
141
token:: CStrRaw ( n) => {
173
- // Raw strings have no escapes, so we only need to check for invalid chars, and we
174
- // can convert the symbol directly to a `Lrc<u8>` on success.
175
- let s = symbol. as_str ( ) ;
176
- let mut error = Ok ( ( ) ) ;
177
- unescape_c_string ( s, Mode :: RawCStr , & mut |_, c| match c {
178
- Ok ( _) => { }
179
- Err ( err) => {
180
- if err. is_fatal ( ) {
181
- error = Err ( LitError :: LexerError ) ;
182
- }
183
- }
184
- } ) ;
185
- error?;
186
- let mut buf = s. to_owned ( ) . into_bytes ( ) ;
142
+ // Raw strings have no escapes so we can convert the symbol
143
+ // directly to a `Lrc<u8>` after appending the terminating NUL
144
+ // char.
145
+ let mut buf = symbol. as_str ( ) . to_owned ( ) . into_bytes ( ) ;
187
146
buf. push ( 0 ) ;
188
147
LitKind :: CStr ( buf. into ( ) , StrStyle :: Raw ( n) )
189
148
}
0 commit comments