@@ -1000,11 +1000,8 @@ impl<'a> Lexer<'a> {
1000
1000
fn read_str_lit ( & mut self ) -> LexResult < Token > {
1001
1001
debug_assert ! ( self . cur( ) == Some ( '\'' ) || self . cur( ) == Some ( '"' ) ) ;
1002
1002
let start = self . cur_pos ( ) ;
1003
- let mut raw = String :: new ( ) ;
1004
1003
let quote = self . cur ( ) . unwrap ( ) ;
1005
1004
1006
- raw. push ( quote) ;
1007
-
1008
1005
self . bump ( ) ; // '"'
1009
1006
1010
1007
self . with_buf ( |l, out| {
@@ -1015,42 +1012,40 @@ impl<'a> Lexer<'a> {
1015
1012
. input
1016
1013
. uncons_while ( |c| c != quote && c != '\\' && !c. is_line_break ( ) ) ;
1017
1014
out. push_str ( s) ;
1018
- raw. push_str ( s) ;
1019
1015
}
1020
1016
l. cur ( )
1021
1017
} {
1022
1018
match c {
1023
1019
c if c == quote => {
1024
- raw. push ( c) ;
1025
-
1026
1020
l. bump ( ) ;
1027
1021
1022
+ let end = l. cur_pos ( ) ;
1023
+
1024
+ let raw = unsafe {
1025
+ // Safety: start and end are valid position because we got them from
1026
+ // `self.input`
1027
+ l. input . slice ( start, end)
1028
+ } ;
1029
+
1028
1030
return Ok ( Token :: Str {
1029
1031
value : l. atoms . atom ( & * out) ,
1030
1032
raw : l. atoms . atom ( raw) ,
1031
1033
} ) ;
1032
1034
}
1033
1035
'\\' => {
1034
- raw. push ( c) ;
1035
-
1036
1036
let mut wrapped = Raw ( Some ( Default :: default ( ) ) ) ;
1037
1037
1038
1038
if let Some ( chars) = l. read_escaped_char ( & mut wrapped, false ) ? {
1039
1039
for c in chars {
1040
1040
out. extend ( c) ;
1041
1041
}
1042
1042
}
1043
-
1044
- raw. push_str ( & wrapped. 0 . unwrap ( ) ) ;
1045
1043
}
1046
1044
c if c. is_line_break ( ) => {
1047
- raw. push ( c) ;
1048
-
1049
1045
break ;
1050
1046
}
1051
1047
_ => {
1052
1048
out. push ( c) ;
1053
- raw. push ( c) ;
1054
1049
1055
1050
l. bump ( ) ;
1056
1051
}
@@ -1059,6 +1054,13 @@ impl<'a> Lexer<'a> {
1059
1054
1060
1055
l. emit_error ( start, SyntaxError :: UnterminatedStrLit ) ;
1061
1056
1057
+ let end = l. cur_pos ( ) ;
1058
+
1059
+ let raw = unsafe {
1060
+ // Safety: start and end are valid position because we got them from
1061
+ // `self.input`
1062
+ l. input . slice ( start, end)
1063
+ } ;
1062
1064
Ok ( Token :: Str {
1063
1065
value : l. atoms . atom ( & * out) ,
1064
1066
raw : l. atoms . atom ( raw) ,
@@ -1160,19 +1162,7 @@ impl<'a> Lexer<'a> {
1160
1162
1161
1163
let mut cooked = Ok ( String :: new ( ) ) ;
1162
1164
let mut cooked_slice_start = start;
1163
- let mut raw = SmartString :: new ( ) ;
1164
- let mut raw_slice_start = start;
1165
-
1166
- macro_rules! consume_raw {
1167
- ( ) => { {
1168
- let last_pos = self . cur_pos( ) ;
1169
- raw. push_str( unsafe {
1170
- // Safety: Both of start and last_pos are valid position because we got them
1171
- // from `self.input`
1172
- self . input. slice( raw_slice_start, last_pos)
1173
- } ) ;
1174
- } } ;
1175
- }
1165
+ let raw_slice_start = start;
1176
1166
1177
1167
macro_rules! consume_cooked {
1178
1168
( ) => { {
@@ -1201,21 +1191,24 @@ impl<'a> Lexer<'a> {
1201
1191
}
1202
1192
1203
1193
consume_cooked ! ( ) ;
1204
- consume_raw ! ( ) ;
1205
1194
1206
1195
// TODO: Handle error
1196
+ let end = self . input . cur_pos ( ) ;
1197
+ let raw = unsafe {
1198
+ // Safety: Both of start and last_pos are valid position because we got them
1199
+ // from `self.input`
1200
+ self . input . slice ( raw_slice_start, end)
1201
+ } ;
1207
1202
return Ok ( Token :: Template {
1208
1203
cooked : cooked. map ( Atom :: from) ,
1209
- raw : self . atoms . atom ( & * raw) ,
1204
+ raw : self . atoms . atom ( raw) ,
1210
1205
} ) ;
1211
1206
}
1212
1207
1213
1208
if c == '\\' {
1214
1209
consume_cooked ! ( ) ;
1215
- consume_raw ! ( ) ;
1216
1210
1217
- raw. push ( '\\' ) ;
1218
- let mut wrapped = Raw ( Some ( raw) ) ;
1211
+ let mut wrapped = Raw ( None ) ;
1219
1212
1220
1213
match self . read_escaped_char ( & mut wrapped, true ) {
1221
1214
Ok ( Some ( chars) ) => {
@@ -1231,17 +1224,13 @@ impl<'a> Lexer<'a> {
1231
1224
}
1232
1225
}
1233
1226
1234
- raw = wrapped. 0 . unwrap ( ) ;
1235
- raw_slice_start = self . cur_pos ( ) ;
1236
1227
cooked_slice_start = self . cur_pos ( ) ;
1237
1228
} else if c. is_line_terminator ( ) {
1238
1229
self . state . had_line_break = true ;
1239
1230
1240
1231
consume_cooked ! ( ) ;
1241
- consume_raw ! ( ) ;
1242
1232
1243
1233
let c = if c == '\r' && self . peek ( ) == Some ( '\n' ) {
1244
- raw. push ( '\r' ) ;
1245
1234
self . bump ( ) ; // '\r'
1246
1235
'\n'
1247
1236
} else {
@@ -1259,8 +1248,6 @@ impl<'a> Lexer<'a> {
1259
1248
if let Ok ( ref mut cooked) = cooked {
1260
1249
cooked. push ( c) ;
1261
1250
}
1262
- raw. push ( c) ;
1263
- raw_slice_start = self . cur_pos ( ) ;
1264
1251
cooked_slice_start = self . cur_pos ( ) ;
1265
1252
} else {
1266
1253
self . bump ( ) ;
0 commit comments