@@ -16,7 +16,6 @@ use core::mem;
1616use core:: ops:: ControlFlow ;
1717use rustc_ast:: ptr:: P ;
1818use rustc_ast:: token:: { self , Delimiter , Token , TokenKind } ;
19- use rustc_ast:: tokenstream:: Spacing ;
2019use rustc_ast:: util:: case:: Case ;
2120use rustc_ast:: util:: classify;
2221use rustc_ast:: util:: parser:: { prec_let_scrutinee_needs_par, AssocOp , Fixity } ;
@@ -999,13 +998,57 @@ impl<'a> Parser<'a> {
999998 }
1000999
10011000 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.
10021003 match self . token . uninterpolate ( ) . kind {
10031004 token:: Ident ( ..) => self . parse_dot_suffix ( base, lo) ,
10041005 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) )
10061009 }
10071010 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+ } )
10091052 }
10101053 _ => {
10111054 self . error_unexpected_after_dot ( ) ;
@@ -1119,41 +1162,6 @@ impl<'a> Parser<'a> {
11191162 }
11201163 }
11211164
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-
11571165 /// Parse the field access used in offset_of, matched by `$(e:expr)+`.
11581166 /// Currently returns a list of idents. However, it should be possible in
11591167 /// future to also do array indices, which might be arbitrary expressions.
@@ -1255,24 +1263,18 @@ impl<'a> Parser<'a> {
12551263 Ok ( fields. into_iter ( ) . collect ( ) )
12561264 }
12571265
1258- fn parse_expr_tuple_field_access (
1266+ fn mk_expr_tuple_field_access (
12591267 & mut self ,
12601268 lo : Span ,
1269+ ident_span : Span ,
12611270 base : P < Expr > ,
12621271 field : Symbol ,
12631272 suffix : Option < Symbol > ,
1264- next_token : Option < ( Token , Spacing ) > ,
12651273 ) -> 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) ) ;
12721274 if let Some ( suffix) = suffix {
1273- self . expect_no_tuple_index_suffix ( span , suffix) ;
1275+ self . expect_no_tuple_index_suffix ( ident_span , suffix) ;
12741276 }
1275- self . mk_expr ( lo. to ( span ) , field)
1277+ self . mk_expr ( lo. to ( ident_span ) , ExprKind :: Field ( base , Ident :: new ( field, ident_span ) ) )
12761278 }
12771279
12781280 /// Parse a function call expression, `expr(...)`.
0 commit comments