@@ -16,7 +16,6 @@ use core::mem;
16
16
use core:: ops:: ControlFlow ;
17
17
use rustc_ast:: ptr:: P ;
18
18
use rustc_ast:: token:: { self , Delimiter , Token , TokenKind } ;
19
- use rustc_ast:: tokenstream:: Spacing ;
20
19
use rustc_ast:: util:: case:: Case ;
21
20
use rustc_ast:: util:: classify;
22
21
use rustc_ast:: util:: parser:: { prec_let_scrutinee_needs_par, AssocOp , Fixity } ;
@@ -999,13 +998,57 @@ impl<'a> Parser<'a> {
999
998
}
1000
999
1001
1000
pub fn parse_dot_suffix_expr ( & mut self , lo : Span , base : P < Expr > ) -> PResult < ' a , P < Expr > > {
1001
+ // At this point we've consumed something like `expr.` and `self.token` holds the token
1002
+ // after the dot.
1002
1003
match self . token . uninterpolate ( ) . kind {
1003
1004
token:: Ident ( ..) => self . parse_dot_suffix ( base, lo) ,
1004
1005
token:: Literal ( token:: Lit { kind : token:: Integer , symbol, suffix } ) => {
1005
- Ok ( self . parse_expr_tuple_field_access ( lo, base, symbol, suffix, None ) )
1006
+ let ident_span = self . token . span ;
1007
+ self . bump ( ) ;
1008
+ Ok ( self . mk_expr_tuple_field_access ( lo, ident_span, base, symbol, suffix) )
1006
1009
}
1007
1010
token:: Literal ( token:: Lit { kind : token:: Float , symbol, suffix } ) => {
1008
- Ok ( self . parse_expr_tuple_field_access_float ( lo, base, symbol, suffix) )
1011
+ Ok ( match self . break_up_float ( symbol, self . token . span ) {
1012
+ // 1e2
1013
+ DestructuredFloat :: Single ( sym, _sp) => {
1014
+ // `foo.1e2`: a single complete dot access, fully consumed. We end up with
1015
+ // the `1e2` token in `self.prev_token` and the following token in
1016
+ // `self.token`.
1017
+ let ident_span = self . token . span ;
1018
+ self . bump ( ) ;
1019
+ self . mk_expr_tuple_field_access ( lo, ident_span, base, sym, suffix)
1020
+ }
1021
+ // 1.
1022
+ DestructuredFloat :: TrailingDot ( sym, ident_span, dot_span) => {
1023
+ // `foo.1.`: a single complete dot access and the start of another.
1024
+ // We end up with the `sym` (`1`) token in `self.prev_token` and a dot in
1025
+ // `self.token`.
1026
+ assert ! ( suffix. is_none( ) ) ;
1027
+ self . token = Token :: new ( token:: Ident ( sym, IdentIsRaw :: No ) , ident_span) ;
1028
+ self . bump_with ( ( Token :: new ( token:: Dot , dot_span) , self . token_spacing ) ) ;
1029
+ self . mk_expr_tuple_field_access ( lo, ident_span, base, sym, None )
1030
+ }
1031
+ // 1.2 | 1.2e3
1032
+ DestructuredFloat :: MiddleDot (
1033
+ sym1,
1034
+ ident1_span,
1035
+ _dot_span,
1036
+ sym2,
1037
+ ident2_span,
1038
+ ) => {
1039
+ // `foo.1.2` (or `foo.1.2e3`): two complete dot accesses. We end up with
1040
+ // the `sym2` (`2` or `2e3`) token in `self.prev_token` and the following
1041
+ // token in `self.token`.
1042
+ let next_token2 =
1043
+ Token :: new ( token:: Ident ( sym2, IdentIsRaw :: No ) , ident2_span) ;
1044
+ self . bump_with ( ( next_token2, self . token_spacing ) ) ;
1045
+ self . bump ( ) ;
1046
+ let base1 =
1047
+ self . mk_expr_tuple_field_access ( lo, ident1_span, base, sym1, None ) ;
1048
+ self . mk_expr_tuple_field_access ( lo, ident2_span, base1, sym2, suffix)
1049
+ }
1050
+ DestructuredFloat :: Error => base,
1051
+ } )
1009
1052
}
1010
1053
_ => {
1011
1054
self . error_unexpected_after_dot ( ) ;
@@ -1119,41 +1162,6 @@ impl<'a> Parser<'a> {
1119
1162
}
1120
1163
}
1121
1164
1122
- fn parse_expr_tuple_field_access_float (
1123
- & mut self ,
1124
- lo : Span ,
1125
- base : P < Expr > ,
1126
- float : Symbol ,
1127
- suffix : Option < Symbol > ,
1128
- ) -> P < Expr > {
1129
- match self . break_up_float ( float, self . token . span ) {
1130
- // 1e2
1131
- DestructuredFloat :: Single ( sym, _sp) => {
1132
- self . parse_expr_tuple_field_access ( lo, base, sym, suffix, None )
1133
- }
1134
- // 1.
1135
- DestructuredFloat :: TrailingDot ( sym, ident_span, dot_span) => {
1136
- assert ! ( suffix. is_none( ) ) ;
1137
- self . token = Token :: new ( token:: Ident ( sym, IdentIsRaw :: No ) , ident_span) ;
1138
- let next_token = ( Token :: new ( token:: Dot , dot_span) , self . token_spacing ) ;
1139
- self . parse_expr_tuple_field_access ( lo, base, sym, None , Some ( next_token) )
1140
- }
1141
- // 1.2 | 1.2e3
1142
- DestructuredFloat :: MiddleDot ( symbol1, ident1_span, dot_span, symbol2, ident2_span) => {
1143
- self . token = Token :: new ( token:: Ident ( symbol1, IdentIsRaw :: No ) , ident1_span) ;
1144
- // This needs to be `Spacing::Alone` to prevent regressions.
1145
- // See issue #76399 and PR #76285 for more details
1146
- let next_token1 = ( Token :: new ( token:: Dot , dot_span) , Spacing :: Alone ) ;
1147
- let base1 =
1148
- self . parse_expr_tuple_field_access ( lo, base, symbol1, None , Some ( next_token1) ) ;
1149
- let next_token2 = Token :: new ( token:: Ident ( symbol2, IdentIsRaw :: No ) , ident2_span) ;
1150
- self . bump_with ( ( next_token2, self . token_spacing ) ) ; // `.`
1151
- self . parse_expr_tuple_field_access ( lo, base1, symbol2, suffix, None )
1152
- }
1153
- DestructuredFloat :: Error => base,
1154
- }
1155
- }
1156
-
1157
1165
/// Parse the field access used in offset_of, matched by `$(e:expr)+`.
1158
1166
/// Currently returns a list of idents. However, it should be possible in
1159
1167
/// future to also do array indices, which might be arbitrary expressions.
@@ -1255,24 +1263,18 @@ impl<'a> Parser<'a> {
1255
1263
Ok ( fields. into_iter ( ) . collect ( ) )
1256
1264
}
1257
1265
1258
- fn parse_expr_tuple_field_access (
1266
+ fn mk_expr_tuple_field_access (
1259
1267
& mut self ,
1260
1268
lo : Span ,
1269
+ ident_span : Span ,
1261
1270
base : P < Expr > ,
1262
1271
field : Symbol ,
1263
1272
suffix : Option < Symbol > ,
1264
- next_token : Option < ( Token , Spacing ) > ,
1265
1273
) -> P < Expr > {
1266
- match next_token {
1267
- Some ( next_token) => self . bump_with ( next_token) ,
1268
- None => self . bump ( ) ,
1269
- }
1270
- let span = self . prev_token . span ;
1271
- let field = ExprKind :: Field ( base, Ident :: new ( field, span) ) ;
1272
1274
if let Some ( suffix) = suffix {
1273
- self . expect_no_tuple_index_suffix ( span , suffix) ;
1275
+ self . expect_no_tuple_index_suffix ( ident_span , suffix) ;
1274
1276
}
1275
- self . mk_expr ( lo. to ( span ) , field)
1277
+ self . mk_expr ( lo. to ( ident_span ) , ExprKind :: Field ( base , Ident :: new ( field, ident_span ) ) )
1276
1278
}
1277
1279
1278
1280
/// Parse a function call expression, `expr(...)`.
0 commit comments