@@ -77,6 +77,8 @@ impl LitKind {
77
77
// new symbol because the string in the LitKind is different to the
78
78
// string in the token.
79
79
let s = symbol. as_str ( ) ;
80
+ // Vanilla strings are so common we optimize for the common case where no chars
81
+ // requiring special behaviour are present.
80
82
let symbol = if s. contains ( [ '\\' , '\r' ] ) {
81
83
let mut buf = String :: with_capacity ( s. len ( ) ) ;
82
84
let mut error = Ok ( ( ) ) ;
@@ -104,27 +106,20 @@ impl LitKind {
104
106
LitKind :: Str ( symbol, ast:: StrStyle :: Cooked )
105
107
}
106
108
token:: StrRaw ( n) => {
107
- // Ditto.
108
- let s = symbol. as_str ( ) ;
109
- let symbol =
110
- if s. contains ( '\r' ) {
111
- let mut buf = String :: with_capacity ( s. len ( ) ) ;
112
- let mut error = Ok ( ( ) ) ;
113
- unescape_literal ( s, Mode :: RawStr , & mut |_, unescaped_char| {
114
- match unescaped_char {
115
- Ok ( c) => buf. push ( c) ,
116
- Err ( err) => {
117
- if err. is_fatal ( ) {
118
- error = Err ( LitError :: LexerError ) ;
119
- }
120
- }
109
+ // Raw strings have no escapes, so we only need to check for invalid chars, and we
110
+ // can reuse the symbol on success.
111
+ let mut error = Ok ( ( ) ) ;
112
+ unescape_literal ( symbol. as_str ( ) , Mode :: RawStr , & mut |_, unescaped_char| {
113
+ match unescaped_char {
114
+ Ok ( _) => { }
115
+ Err ( err) => {
116
+ if err. is_fatal ( ) {
117
+ error = Err ( LitError :: LexerError ) ;
121
118
}
122
- } ) ;
123
- error?;
124
- Symbol :: intern ( & buf)
125
- } else {
126
- symbol
127
- } ;
119
+ }
120
+ }
121
+ } ) ;
122
+ error?;
128
123
LitKind :: Str ( symbol, ast:: StrStyle :: Raw ( n) )
129
124
}
130
125
token:: ByteStr => {
@@ -143,25 +138,19 @@ impl LitKind {
143
138
LitKind :: ByteStr ( buf. into ( ) , StrStyle :: Cooked )
144
139
}
145
140
token:: ByteStrRaw ( n) => {
141
+ // Raw strings have no escapes, so we only need to check for invalid chars, and we
142
+ // can convert the symbol directly to a `Lrc<u8>` on success.
146
143
let s = symbol. as_str ( ) ;
147
- let bytes = if s. contains ( '\r' ) {
148
- let mut buf = Vec :: with_capacity ( s. len ( ) ) ;
149
- let mut error = Ok ( ( ) ) ;
150
- unescape_literal ( s, Mode :: RawByteStr , & mut |_, c| match c {
151
- Ok ( c) => buf. push ( byte_from_char ( c) ) ,
152
- Err ( err) => {
153
- if err. is_fatal ( ) {
154
- error = Err ( LitError :: LexerError ) ;
155
- }
144
+ let mut error = Ok ( ( ) ) ;
145
+ unescape_literal ( s, Mode :: RawByteStr , & mut |_, c| match c {
146
+ Ok ( _) => { }
147
+ Err ( err) => {
148
+ if err. is_fatal ( ) {
149
+ error = Err ( LitError :: LexerError ) ;
156
150
}
157
- } ) ;
158
- error?;
159
- buf
160
- } else {
161
- symbol. to_string ( ) . into_bytes ( )
162
- } ;
163
-
164
- LitKind :: ByteStr ( bytes. into ( ) , StrStyle :: Raw ( n) )
151
+ }
152
+ } ) ;
153
+ LitKind :: ByteStr ( s. to_owned ( ) . into_bytes ( ) . into ( ) , StrStyle :: Raw ( n) )
165
154
}
166
155
token:: CStr => {
167
156
let s = symbol. as_str ( ) ;
@@ -172,7 +161,6 @@ impl LitKind {
172
161
error = Err ( LitError :: NulInCStr ( span) ) ;
173
162
}
174
163
Ok ( CStrUnit :: Byte ( b) ) => buf. push ( b) ,
175
- Ok ( CStrUnit :: Char ( c) ) if c. len_utf8 ( ) == 1 => buf. push ( c as u8 ) ,
176
164
Ok ( CStrUnit :: Char ( c) ) => {
177
165
buf. extend_from_slice ( c. encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) )
178
166
}
@@ -187,25 +175,23 @@ impl LitKind {
187
175
LitKind :: CStr ( buf. into ( ) , StrStyle :: Cooked )
188
176
}
189
177
token:: CStrRaw ( n) => {
178
+ // Raw strings have no escapes, so we only need to check for invalid chars, and we
179
+ // can convert the symbol directly to a `Lrc<u8>` on success.
190
180
let s = symbol. as_str ( ) ;
191
- let mut buf = Vec :: with_capacity ( s. len ( ) ) ;
192
181
let mut error = Ok ( ( ) ) ;
193
182
unescape_c_string ( s, Mode :: RawCStr , & mut |span, c| match c {
194
183
Ok ( CStrUnit :: Byte ( 0 ) | CStrUnit :: Char ( '\0' ) ) => {
195
184
error = Err ( LitError :: NulInCStr ( span) ) ;
196
185
}
197
- Ok ( CStrUnit :: Byte ( b) ) => buf. push ( b) ,
198
- Ok ( CStrUnit :: Char ( c) ) if c. len_utf8 ( ) == 1 => buf. push ( c as u8 ) ,
199
- Ok ( CStrUnit :: Char ( c) ) => {
200
- buf. extend_from_slice ( c. encode_utf8 ( & mut [ 0 ; 4 ] ) . as_bytes ( ) )
201
- }
186
+ Ok ( _) => { }
202
187
Err ( err) => {
203
188
if err. is_fatal ( ) {
204
189
error = Err ( LitError :: LexerError ) ;
205
190
}
206
191
}
207
192
} ) ;
208
193
error?;
194
+ let mut buf = s. to_owned ( ) . into_bytes ( ) ;
209
195
buf. push ( 0 ) ;
210
196
LitKind :: CStr ( buf. into ( ) , StrStyle :: Raw ( n) )
211
197
}
0 commit comments