about summary refs log tree commit diff
path: root/compiler
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
parent59ecbd2cea20839f1288b917cbf5ba8c23864df7 (diff)
downloadrust-5eb29c7f49c2d99e9bfc778f30984f7fdcf5fc08.tar.gz
rust-5eb29c7f49c2d99e9bfc778f30984f7fdcf5fc08.zip
Migrate offset_of from a macro to builtin # syntax
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs3
-rw-r--r--compiler/rustc_builtin_macros/messages.ftl4
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/offset_of.rs99
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs20
-rw-r--r--compiler/rustc_span/src/symbol.rs1
6 files changed, 21 insertions, 108 deletions
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index b74c59bca30..87c32ffce12 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -556,8 +556,7 @@ impl<'a> State<'a> {
                 self.pclose();
             }
             ast::ExprKind::OffsetOf(container, fields) => {
-                // FIXME: This should have its own syntax, distinct from a macro invocation.
-                self.word("offset_of!");
+                self.word("builtin # offset_of");
                 self.popen();
                 self.rbox(0, Inconsistent);
                 self.print_type(container);
diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl
index 0d7cf7cdb26..3b458b1d30b 100644
--- a/compiler/rustc_builtin_macros/messages.ftl
+++ b/compiler/rustc_builtin_macros/messages.ftl
@@ -150,10 +150,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
     *[more] arguments
     } in format string, but {$desc}
 
-builtin_macros_offset_of_expected_field = expected field
-
-builtin_macros_offset_of_expected_two_args = expected 2 arguments
-
 builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
 
 builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index c7da61d72b3..4e5edb4d6b1 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -44,7 +44,6 @@ mod format;
 mod format_foreign;
 mod global_allocator;
 mod log_syntax;
-mod offset_of;
 mod source_util;
 mod test;
 mod trace_macros;
@@ -92,7 +91,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         line: source_util::expand_line,
         log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
-        offset_of: offset_of::expand_offset_of,
         option_env: env::expand_option_env,
         core_panic: edition_panic::expand_panic,
         std_panic: edition_panic::expand_panic,
diff --git a/compiler/rustc_builtin_macros/src/offset_of.rs b/compiler/rustc_builtin_macros/src/offset_of.rs
deleted file mode 100644
index 0ef3e000e41..00000000000
--- a/compiler/rustc_builtin_macros/src/offset_of.rs
+++ /dev/null
@@ -1,99 +0,0 @@
-use rustc_ast as ast;
-use rustc_ast::ptr::P;
-use rustc_ast::token;
-use rustc_ast::tokenstream::TokenStream;
-use rustc_errors::PResult;
-use rustc_expand::base::{self, *};
-use rustc_macros::Diagnostic;
-use rustc_parse::parser::Parser;
-use rustc_span::{symbol::Ident, Span};
-
-#[derive(Diagnostic)]
-#[diag(builtin_macros_offset_of_expected_field)]
-struct ExpectedField {
-    #[primary_span]
-    span: Span,
-}
-
-#[derive(Diagnostic)]
-#[diag(builtin_macros_offset_of_expected_two_args)]
-struct ExpectedTwoArgs {
-    #[primary_span]
-    span: Span,
-}
-
-fn parse_field<'a>(cx: &ExtCtxt<'a>, p: &mut Parser<'a>) -> PResult<'a, Ident> {
-    let token = p.token.uninterpolate();
-    let field = match token.kind {
-        token::Ident(name, _) => Ident::new(name, token.span),
-        token::Literal(token::Lit { kind: token::Integer, symbol, suffix: None }) => {
-            Ident::new(symbol, token.span)
-        }
-        _ => return Err(cx.create_err(ExpectedField { span: p.token.span })),
-    };
-
-    p.bump();
-
-    Ok(field)
-}
-
-fn parse_args<'a>(
-    cx: &mut ExtCtxt<'a>,
-    sp: Span,
-    tts: TokenStream,
-) -> PResult<'a, (P<ast::Ty>, P<[Ident]>)> {
-    let mut p = cx.new_parser_from_tts(tts);
-
-    let container = p.parse_ty()?;
-
-    p.expect(&token::Comma)?;
-
-    if p.eat(&token::Eof) {
-        return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
-    }
-
-    let mut fields = Vec::new();
-
-    loop {
-        let field = parse_field(cx, &mut p)?;
-        fields.push(field);
-
-        if p.eat(&token::Dot) {
-            continue;
-        }
-
-        p.eat(&token::Comma);
-
-        if !p.eat(&token::Eof) {
-            return Err(cx.create_err(ExpectedTwoArgs { span: sp }));
-        }
-
-        break;
-    }
-
-    Ok((container, fields.into()))
-}
-
-pub fn expand_offset_of<'cx>(
-    cx: &'cx mut ExtCtxt<'_>,
-    sp: Span,
-    tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
-    match parse_args(cx, sp, tts) {
-        Ok((container, fields)) => {
-            let expr = P(ast::Expr {
-                id: ast::DUMMY_NODE_ID,
-                kind: ast::ExprKind::OffsetOf(container, fields),
-                span: sp,
-                attrs: ast::AttrVec::new(),
-                tokens: None,
-            });
-
-            MacEager::expr(expr)
-        }
-        Err(mut err) => {
-            err.emit();
-            DummyResult::any(sp)
-        }
-    }
-}
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.
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9e543fc8de4..d54a615dd4a 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -441,6 +441,7 @@ symbols! {
         breakpoint,
         bridge,
         bswap,
+        builtin_syntax,
         c_str,
         c_str_literals,
         c_unwind,