about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorest31 <MTest31@outlook.com>2023-04-22 16:29:34 +0200
committerest31 <MTest31@outlook.com>2023-05-05 21:44:13 +0200
commit5eb29c7f49c2d99e9bfc778f30984f7fdcf5fc08 (patch)
tree488994893924ca3c1a51acf4e5cadb46949a905c /compiler/rustc_parse/src
parent59ecbd2cea20839f1288b917cbf5ba8c23864df7 (diff)
downloadrust-5eb29c7f49c2d99e9bfc778f30984f7fdcf5fc08.tar.gz
rust-5eb29c7f49c2d99e9bfc778f30984f7fdcf5fc08.zip
Migrate offset_of from a macro to builtin # syntax
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs20
1 files changed, 19 insertions, 1 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 844cf335962..b84a088a7b7 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -1759,7 +1759,11 @@ impl<'a> Parser<'a> {
 
     /// Parse `builtin # ident(args,*)`.
     fn parse_expr_builtin(&mut self) -> PResult<'a, P<Expr>> {
-        self.parse_builtin(|_this, _lo, _ident| {
+        self.parse_builtin(|this, lo, ident| {
+            if ident.name == sym::offset_of {
+                return Ok(Some(this.parse_expr_offset_of(lo)?));
+            }
+
             Ok(None)
         })
     }
@@ -1793,6 +1797,20 @@ impl<'a> Parser<'a> {
         ret
     }
 
+    pub(crate) fn parse_expr_offset_of(&mut self, lo: Span) -> PResult<'a, P<Expr>> {
+        let container = self.parse_ty()?;
+        self.expect(&TokenKind::Comma)?;
+
+        let seq_sep = SeqSep { sep: Some(token::Dot), trailing_sep_allowed: false };
+        let (fields, _trailing, _recovered) = self.parse_seq_to_before_end(
+            &TokenKind::CloseDelim(Delimiter::Parenthesis),
+            seq_sep,
+            Parser::parse_field_name,
+        )?;
+        let span = lo.to(self.token.span);
+        Ok(self.mk_expr(span, ExprKind::OffsetOf(container, fields.to_vec().into())))
+    }
+
     /// Returns a string literal if the next token is a string literal.
     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
     /// and returns `None` if the next token is not literal at all.