@@ -18,6 +18,7 @@ use rustc_span::symbol::Symbol;
18
18
use rustc_span:: { BytePos , Pos , Span } ;
19
19
use tracing:: debug;
20
20
21
+ use crate :: lexer:: diagnostics:: TokenTreeDiagInfo ;
21
22
use crate :: lexer:: unicode_chars:: UNICODE_ARRAY ;
22
23
use crate :: { errors, make_unclosed_delims_error} ;
23
24
@@ -56,7 +57,7 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
56
57
}
57
58
58
59
let cursor = Cursor :: new ( src) ;
59
- let string_reader = StringReader {
60
+ let mut lexer = Lexer {
60
61
psess,
61
62
start_pos,
62
63
pos : start_pos,
@@ -65,34 +66,31 @@ pub(crate) fn lex_token_trees<'psess, 'src>(
65
66
override_span,
66
67
nbsp_is_whitespace : false ,
67
68
last_lifetime : None ,
69
+ token : Token :: dummy ( ) ,
70
+ diag_info : TokenTreeDiagInfo :: default ( ) ,
68
71
} ;
69
- let ( stream, res, unmatched_delims) =
70
- tokentrees:: TokenTreesReader :: lex_all_token_trees ( string_reader) ;
71
- match res {
72
- Ok ( ( ) ) if unmatched_delims. is_empty ( ) => Ok ( stream) ,
73
- _ => {
74
- // Return error if there are unmatched delimiters or unclosed delimiters.
75
- // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
76
- // because the delimiter mismatch is more likely to be the root cause of error
77
-
78
- let mut buffer = Vec :: with_capacity ( 1 ) ;
79
- for unmatched in unmatched_delims {
80
- if let Some ( err) = make_unclosed_delims_error ( unmatched, psess) {
81
- buffer. push ( err) ;
82
- }
83
- }
84
- if let Err ( errs) = res {
85
- // Add unclosing delimiter or diff marker errors
86
- for err in errs {
87
- buffer. push ( err) ;
88
- }
89
- }
90
- Err ( buffer)
72
+ let ( _open_spacing, stream, res) = lexer. lex_token_trees ( /* is_delimited */ false ) ;
73
+ let unmatched_delims = lexer. diag_info . unmatched_delims ;
74
+
75
+ if res. is_ok ( ) && unmatched_delims. is_empty ( ) {
76
+ Ok ( stream)
77
+ } else {
78
+ // Return error if there are unmatched delimiters or unclosed delimiters.
79
+ // We emit delimiter mismatch errors first, then emit the unclosing delimiter mismatch
80
+ // because the delimiter mismatch is more likely to be the root cause of error
81
+ let mut buffer: Vec < _ > = unmatched_delims
82
+ . into_iter ( )
83
+ . filter_map ( |unmatched_delim| make_unclosed_delims_error ( unmatched_delim, psess) )
84
+ . collect ( ) ;
85
+ if let Err ( errs) = res {
86
+ // Add unclosing delimiter or diff marker errors
87
+ buffer. extend ( errs) ;
91
88
}
89
+ Err ( buffer)
92
90
}
93
91
}
94
92
95
- struct StringReader < ' psess , ' src > {
93
+ struct Lexer < ' psess , ' src > {
96
94
psess : & ' psess ParseSess ,
97
95
/// Initial position, read-only.
98
96
start_pos : BytePos ,
@@ -111,9 +109,14 @@ struct StringReader<'psess, 'src> {
111
109
/// Track the `Span` for the leading `'` of the last lifetime. Used for
112
110
/// diagnostics to detect possible typo where `"` was meant.
113
111
last_lifetime : Option < Span > ,
112
+
113
+ /// The current token.
114
+ token : Token ,
115
+
116
+ diag_info : TokenTreeDiagInfo ,
114
117
}
115
118
116
- impl < ' psess , ' src > StringReader < ' psess , ' src > {
119
+ impl < ' psess , ' src > Lexer < ' psess , ' src > {
117
120
fn dcx ( & self ) -> DiagCtxtHandle < ' psess > {
118
121
self . psess . dcx ( )
119
122
}
@@ -124,7 +127,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
124
127
125
128
/// Returns the next token, paired with a bool indicating if the token was
126
129
/// preceded by whitespace.
127
- fn next_token ( & mut self ) -> ( Token , bool ) {
130
+ fn next_token_from_cursor ( & mut self ) -> ( Token , bool ) {
128
131
let mut preceded_by_whitespace = false ;
129
132
let mut swallow_next_invalid = 0 ;
130
133
// Skip trivial (whitespace & comments) tokens
@@ -231,7 +234,8 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
231
234
. push ( span) ;
232
235
token:: Ident ( sym, IdentIsRaw :: No )
233
236
}
234
- // split up (raw) c string literals to an ident and a string literal when edition < 2021.
237
+ // split up (raw) c string literals to an ident and a string literal when edition <
238
+ // 2021.
235
239
rustc_lexer:: TokenKind :: Literal {
236
240
kind : kind @ ( LiteralKind :: CStr { .. } | LiteralKind :: RawCStr { .. } ) ,
237
241
suffix_start : _,
@@ -252,7 +256,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
252
256
let prefix_span = self . mk_sp ( start, lit_start) ;
253
257
return ( Token :: new ( self . ident ( start) , prefix_span) , preceded_by_whitespace) ;
254
258
}
255
- rustc_lexer:: TokenKind :: GuardedStrPrefix => self . maybe_report_guarded_str ( start, str_before) ,
259
+ rustc_lexer:: TokenKind :: GuardedStrPrefix => {
260
+ self . maybe_report_guarded_str ( start, str_before)
261
+ }
256
262
rustc_lexer:: TokenKind :: Literal { kind, suffix_start } => {
257
263
let suffix_start = start + BytePos ( suffix_start) ;
258
264
let ( kind, symbol) = self . cook_lexer_literal ( start, suffix_start, kind) ;
@@ -296,13 +302,20 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
296
302
if prefix_span. at_least_rust_2021 ( ) {
297
303
let span = self . mk_sp ( start, self . pos ) ;
298
304
299
- let lifetime_name_without_tick = Symbol :: intern ( & self . str_from ( ident_start) ) ;
305
+ let lifetime_name_without_tick =
306
+ Symbol :: intern ( & self . str_from ( ident_start) ) ;
300
307
if !lifetime_name_without_tick. can_be_raw ( ) {
301
- self . dcx ( ) . emit_err ( errors:: CannotBeRawLifetime { span, ident : lifetime_name_without_tick } ) ;
308
+ self . dcx ( ) . emit_err (
309
+ errors:: CannotBeRawLifetime {
310
+ span,
311
+ ident : lifetime_name_without_tick
312
+ }
313
+ ) ;
302
314
}
303
315
304
316
// Put the `'` back onto the lifetime name.
305
- let mut lifetime_name = String :: with_capacity ( lifetime_name_without_tick. as_str ( ) . len ( ) + 1 ) ;
317
+ let mut lifetime_name =
318
+ String :: with_capacity ( lifetime_name_without_tick. as_str ( ) . len ( ) + 1 ) ;
306
319
lifetime_name. push ( '\'' ) ;
307
320
lifetime_name += lifetime_name_without_tick. as_str ( ) ;
308
321
let sym = Symbol :: intern ( & lifetime_name) ;
0 commit comments