@@ -95,23 +95,32 @@ enum PrevTokenKind {
95
95
Other ,
96
96
}
97
97
98
- // NOTE: `Ident`s are handled by `common.rs`.
99
-
100
98
#[ derive( Clone ) ]
101
99
pub struct Parser < ' a > {
102
100
pub sess : & ' a ParseSess ,
103
101
/// The current normalized token.
104
102
/// "Normalized" means that some interpolated tokens
105
103
/// (`$i: ident` and `$l: lifetime` meta-variables) are replaced
106
104
/// with non-interpolated identifier and lifetime tokens they refer to.
107
- /// Perhaps the normalized / non-normalized setup can be simplified somehow .
105
+ /// Use span from this token if you need an isolated span .
108
106
pub token : Token ,
109
- /// The span of the current non-normalized token.
110
- meta_var_span : Option < Span > ,
111
- /// The span of the previous non-normalized token.
112
- pub prev_span : Span ,
113
- /// The kind of the previous normalized token (in simplified form).
107
+ /// The current non-normalized token if it's different from `token`.
108
+ /// Preferable use is through the `unnormalized_token()` getter.
109
+ /// Use span from this token if you need to concatenate it with some neighbouring spans.
110
+ unnormalized_token : Option < Token > ,
111
+ /// The previous normalized token.
112
+ /// Use span from this token if you need an isolated span.
113
+ prev_token : Token ,
114
+ /// The previous non-normalized token if it's different from `prev_token`.
115
+ /// Preferable use is through the `unnormalized_prev_token()` getter.
116
+ /// Use span from this token if you need to concatenate it with some neighbouring spans.
117
+ unnormalized_prev_token : Option < Token > ,
118
+ /// Equivalent to `prev_token.kind` in simplified form.
119
+ /// FIXME: Remove in favor of `(unnormalized_)prev_token().kind`.
114
120
prev_token_kind : PrevTokenKind ,
121
+ /// Equivalent to `unnormalized_prev_token().span`.
122
+ /// FIXME: Remove in favor of `(unnormalized_)prev_token().span`.
123
+ pub prev_span : Span ,
115
124
restrictions : Restrictions ,
116
125
/// Used to determine the path to externally loaded source files.
117
126
pub ( super ) directory : Directory < ' a > ,
@@ -384,9 +393,11 @@ impl<'a> Parser<'a> {
384
393
let mut parser = Parser {
385
394
sess,
386
395
token : Token :: dummy ( ) ,
387
- prev_span : DUMMY_SP ,
388
- meta_var_span : None ,
396
+ unnormalized_token : None ,
397
+ prev_token : Token :: dummy ( ) ,
398
+ unnormalized_prev_token : None ,
389
399
prev_token_kind : PrevTokenKind :: Other ,
400
+ prev_span : DUMMY_SP ,
390
401
restrictions : Restrictions :: empty ( ) ,
391
402
recurse_into_file_modules,
392
403
directory : Directory {
@@ -427,6 +438,14 @@ impl<'a> Parser<'a> {
427
438
parser
428
439
}
429
440
441
+ fn unnormalized_token ( & self ) -> & Token {
442
+ self . unnormalized_token . as_ref ( ) . unwrap_or ( & self . token )
443
+ }
444
+
445
+ fn unnormalized_prev_token ( & self ) -> & Token {
446
+ self . unnormalized_prev_token . as_ref ( ) . unwrap_or ( & self . prev_token )
447
+ }
448
+
430
449
fn next_tok ( & mut self ) -> Token {
431
450
let mut next = if self . desugar_doc_comments {
432
451
self . token_cursor . next_desugared ( )
@@ -435,7 +454,7 @@ impl<'a> Parser<'a> {
435
454
} ;
436
455
if next. span . is_dummy ( ) {
437
456
// Tweak the location for better diagnostics, but keep syntactic context intact.
438
- next. span = self . prev_span . with_ctxt ( next. span . ctxt ( ) ) ;
457
+ next. span = self . unnormalized_token ( ) . span . with_ctxt ( next. span . ctxt ( ) ) ;
439
458
}
440
459
next
441
460
}
@@ -895,10 +914,13 @@ impl<'a> Parser<'a> {
895
914
self . span_bug ( self . token . span , msg) ;
896
915
}
897
916
898
- self . prev_span = self . meta_var_span . take ( ) . unwrap_or ( self . token . span ) ;
917
+ // Update the current and previous tokens.
918
+ let next_token = self . next_tok ( ) ;
919
+ self . prev_token = mem:: replace ( & mut self . token , next_token) ;
920
+ self . unnormalized_prev_token = self . unnormalized_token . take ( ) ;
899
921
900
- // Record last token kind for possible error recovery .
901
- self . prev_token_kind = match self . token . kind {
922
+ // Update fields derived from the previous token .
923
+ self . prev_token_kind = match self . prev_token . kind {
902
924
token:: DocComment ( ..) => PrevTokenKind :: DocComment ,
903
925
token:: Comma => PrevTokenKind :: Comma ,
904
926
token:: BinOp ( token:: Plus ) => PrevTokenKind :: Plus ,
@@ -908,22 +930,28 @@ impl<'a> Parser<'a> {
908
930
token:: Ident ( ..) => PrevTokenKind :: Ident ,
909
931
_ => PrevTokenKind :: Other ,
910
932
} ;
933
+ self . prev_span = self . unnormalized_prev_token ( ) . span ;
911
934
912
- self . token = self . next_tok ( ) ;
913
935
self . expected_tokens . clear ( ) ;
914
936
// Check after each token.
915
937
self . process_potential_macro_variable ( ) ;
916
938
}
917
939
918
940
/// Advances the parser using provided token as a next one. Use this when
919
941
/// consuming a part of a token. For example a single `<` from `<<`.
942
+ /// FIXME: this function sets the previous token data to some semi-nonsensical values
943
+ /// which kind of work because they are currently used in very limited ways in practice.
944
+ /// Correct token kinds and spans need to be calculated instead.
920
945
fn bump_with ( & mut self , next : TokenKind , span : Span ) {
921
- self . prev_span = self . token . span . with_hi ( span. lo ( ) ) ;
922
- // It would be incorrect to record the kind of the current token, but
923
- // fortunately for tokens currently using `bump_with`, the
924
- // `prev_token_kind` will be of no use anyway.
946
+ // Update the current and previous tokens.
947
+ let next_token = Token :: new ( next, span) ;
948
+ self . prev_token = mem:: replace ( & mut self . token , next_token) ;
949
+ self . unnormalized_prev_token = self . unnormalized_token . take ( ) ;
950
+
951
+ // Update fields derived from the previous token.
925
952
self . prev_token_kind = PrevTokenKind :: Other ;
926
- self . token = Token :: new ( next, span) ;
953
+ self . prev_span = self . unnormalized_prev_token ( ) . span . with_hi ( span. lo ( ) ) ;
954
+
927
955
self . expected_tokens . clear ( ) ;
928
956
}
929
957
@@ -1054,7 +1082,7 @@ impl<'a> Parser<'a> {
1054
1082
}
1055
1083
1056
1084
pub fn process_potential_macro_variable ( & mut self ) {
1057
- self . token = match self . token . kind {
1085
+ let normalized_token = match self . token . kind {
1058
1086
token:: Dollar
1059
1087
if self . token . span . from_expansion ( ) && self . look_ahead ( 1 , |t| t. is_ident ( ) ) =>
1060
1088
{
@@ -1071,7 +1099,6 @@ impl<'a> Parser<'a> {
1071
1099
return ;
1072
1100
}
1073
1101
token:: Interpolated ( ref nt) => {
1074
- self . meta_var_span = Some ( self . token . span ) ;
1075
1102
// Interpolated identifier and lifetime tokens are replaced with usual identifier
1076
1103
// and lifetime tokens, so the former are never encountered during normal parsing.
1077
1104
match * * nt {
@@ -1084,6 +1111,7 @@ impl<'a> Parser<'a> {
1084
1111
}
1085
1112
_ => return ,
1086
1113
} ;
1114
+ self . unnormalized_token = Some ( mem:: replace ( & mut self . token , normalized_token) ) ;
1087
1115
}
1088
1116
1089
1117
/// Parses a single token tree from the input.
@@ -1100,7 +1128,7 @@ impl<'a> Parser<'a> {
1100
1128
}
1101
1129
token:: CloseDelim ( _) | token:: Eof => unreachable ! ( ) ,
1102
1130
_ => {
1103
- let token = self . token . take ( ) ;
1131
+ let token = self . token . clone ( ) ;
1104
1132
self . bump ( ) ;
1105
1133
TokenTree :: Token ( token)
1106
1134
}
0 commit comments