diff options
| author | est31 <MTest31@outlook.com> | 2023-06-02 18:53:04 +0200 |
|---|---|---|
| committer | est31 <MTest31@outlook.com> | 2023-06-08 23:42:58 +0200 |
| commit | 1b90f5efaf46073a7da509a895a0688e1c6300c3 (patch) | |
| tree | 1dfa03e86f163a72e16a6d62df81f0aead4684c6 /compiler/rustc_parse | |
| parent | d74ec96e8d334c765e35707f7b7f3c6499a1b43c (diff) | |
| download | rust-1b90f5efaf46073a7da509a895a0688e1c6300c3.tar.gz rust-1b90f5efaf46073a7da509a895a0688e1c6300c3.zip | |
Support float-like tuple indices in offset_of!()
The tokenizer gives us whole float literal tokens, we have to split them up in order to be able to create field access from them.
Diffstat (limited to 'compiler/rustc_parse')
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 9e5f85dc7dc..df06115ef3b 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1852,10 +1852,53 @@ impl<'a> Parser<'a> { let (fields, _trailing, _recovered) = self.parse_seq_to_before_end( &TokenKind::CloseDelim(Delimiter::Parenthesis), seq_sep, - Parser::parse_field_name, + |this| { + let token::Literal(token::Lit { kind: token::Float, symbol, suffix }) = this.token.kind + else { + return Ok(thin_vec![this.parse_field_name()?]); + }; + let res = match this.break_up_float(symbol) { + // 1e2 + DestructuredFloat::Single(sym, sp) => { + this.bump(); + thin_vec![Ident::new(sym, sp)] + } + // 1. + DestructuredFloat::TrailingDot(sym, sym_span, dot_span) => { + assert!(suffix.is_none()); + // Analogous to Self::break_and_eat + this.token_cursor.break_last_token = true; + // This might work, in cases like `1. 2.3`, and might not, + // in cases like `offset_of!(Ty, 1.)`. + this.token = Token::new(token::Ident(sym, false), sym_span); + this.bump_with((Token::new(token::Dot, dot_span), this.token_spacing)); + thin_vec![Ident::new(sym, sym_span)] + } + // 1.2 | 1.2e3 + DestructuredFloat::MiddleDot( + symbol1, + ident1_span, + _dot_span, + symbol2, + ident2_span, + ) => { + this.bump(); + thin_vec![ + Ident::new(symbol1, ident1_span), + Ident::new(symbol2, ident2_span) + ] + } + DestructuredFloat::Error => { + this.bump(); + thin_vec![Ident::new(symbol, this.prev_token.span)] + } + }; + Ok(res) + }, )?; + let fields = fields.into_iter().flatten().collect::<Vec<_>>(); let span = lo.to(self.token.span); - Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.to_vec().into()))) + Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.into()))) } /// Returns a string literal if the next token is a string literal. |
