Skip to content

Commit 80a2ec4

Browse files
committed
Auto merge of #106934 - DrMeepster:offset_of, r=WaffleLapkin
Add offset_of! macro (RFC 3308) Implements rust-lang/rfcs#3308 (tracking issue #106655) by adding the built in macro `core::mem::offset_of`. Two of the future possibilities are also implemented: * Nested field accesses (without array indexing) * DST support (for `Sized` fields) I wrote this a few months ago, before the RFC merged. Now that it's merged, I decided to rebase and finish it. cc `@thomcc` (RFC author)
2 parents 0fd50f3 + 99abe44 commit 80a2ec4

File tree

83 files changed

+1355
-42
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+1355
-42
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,7 @@ impl Expr {
12711271
ExprKind::Continue(..) => ExprPrecedence::Continue,
12721272
ExprKind::Ret(..) => ExprPrecedence::Ret,
12731273
ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
1274+
ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
12741275
ExprKind::MacCall(..) => ExprPrecedence::Mac,
12751276
ExprKind::Struct(..) => ExprPrecedence::Struct,
12761277
ExprKind::Repeat(..) => ExprPrecedence::Repeat,
@@ -1469,6 +1470,9 @@ pub enum ExprKind {
14691470
/// Output of the `asm!()` macro.
14701471
InlineAsm(P<InlineAsm>),
14711472

1473+
/// Output of the `offset_of!()` macro.
1474+
OffsetOf(P<Ty>, P<[Ident]>),
1475+
14721476
/// A macro invocation; pre-expansion.
14731477
MacCall(P<MacCall>),
14741478

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,6 +1456,12 @@ pub fn noop_visit_expr<T: MutVisitor>(
14561456
}
14571457
ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
14581458
ExprKind::FormatArgs(fmt) => vis.visit_format_args(fmt),
1459+
ExprKind::OffsetOf(container, fields) => {
1460+
vis.visit_ty(container);
1461+
for field in fields.iter_mut() {
1462+
vis.visit_ident(field);
1463+
}
1464+
}
14591465
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
14601466
ExprKind::Struct(se) => {
14611467
let StructExpr { qself, path, fields, rest } = se.deref_mut();

compiler/rustc_ast/src/util/parser.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ pub enum ExprPrecedence {
269269
Index,
270270
Try,
271271
InlineAsm,
272+
OffsetOf,
272273
Mac,
273274
FormatArgs,
274275

@@ -335,7 +336,8 @@ impl ExprPrecedence {
335336
| ExprPrecedence::Try
336337
| ExprPrecedence::InlineAsm
337338
| ExprPrecedence::Mac
338-
| ExprPrecedence::FormatArgs => PREC_POSTFIX,
339+
| ExprPrecedence::FormatArgs
340+
| ExprPrecedence::OffsetOf => PREC_POSTFIX,
339341

340342
// Never need parens
341343
ExprPrecedence::Array

compiler/rustc_ast/src/visit.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,12 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
909909
ExprKind::Paren(subexpression) => visitor.visit_expr(subexpression),
910910
ExprKind::InlineAsm(asm) => visitor.visit_inline_asm(asm),
911911
ExprKind::FormatArgs(f) => visitor.visit_format_args(f),
912+
ExprKind::OffsetOf(container, fields) => {
913+
visitor.visit_ty(container);
914+
for &field in fields {
915+
visitor.visit_ident(field);
916+
}
917+
}
912918
ExprKind::Yield(optional_expression) => {
913919
walk_list!(visitor, visit_expr, optional_expression);
914920
}

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
289289
hir::ExprKind::InlineAsm(self.lower_inline_asm(e.span, asm))
290290
}
291291
ExprKind::FormatArgs(fmt) => self.lower_format_args(e.span, fmt),
292+
ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf(
293+
self.lower_ty(
294+
container,
295+
&mut ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
296+
),
297+
self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
298+
),
292299
ExprKind::Struct(se) => {
293300
let rest = match &se.rest {
294301
StructRest::Base(e) => Some(self.lower_expr(e)),

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ enum ImplTraitPosition {
283283
FieldTy,
284284
Cast,
285285
ImplSelf,
286+
OffsetOf,
286287
}
287288

288289
impl std::fmt::Display for ImplTraitPosition {
@@ -313,6 +314,7 @@ impl std::fmt::Display for ImplTraitPosition {
313314
ImplTraitPosition::FieldTy => "field types",
314315
ImplTraitPosition::Cast => "cast types",
315316
ImplTraitPosition::ImplSelf => "impl headers",
317+
ImplTraitPosition::OffsetOf => "`offset_of!` params",
316318
};
317319

318320
write!(f, "{name}")

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,26 @@ impl<'a> State<'a> {
549549
self.end();
550550
self.pclose();
551551
}
552+
ast::ExprKind::OffsetOf(container, fields) => {
553+
// FIXME: This should have its own syntax, distinct from a macro invocation.
554+
self.word("offset_of!");
555+
self.popen();
556+
self.rbox(0, Inconsistent);
557+
self.print_type(container);
558+
self.word(",");
559+
self.space();
560+
561+
if let Some((&first, rest)) = fields.split_first() {
562+
self.print_ident(first);
563+
564+
for &field in rest {
565+
self.word(".");
566+
self.print_ident(field);
567+
}
568+
}
569+
570+
self.end();
571+
}
552572
ast::ExprKind::MacCall(m) => self.print_mac(m),
553573
ast::ExprKind::Paren(e) => {
554574
self.popen();

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2306,7 +2306,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
23062306
Rvalue::AddressOf(..)
23072307
| Rvalue::ThreadLocalRef(..)
23082308
| Rvalue::Len(..)
2309-
| Rvalue::Discriminant(..) => {}
2309+
| Rvalue::Discriminant(..)
2310+
| Rvalue::NullaryOp(NullOp::OffsetOf(..), _) => {}
23102311
}
23112312
}
23122313

compiler/rustc_builtin_macros/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,6 @@ builtin_macros_format_pos_mismatch = {$n} positional {$n ->
149149
[one] argument
150150
*[more] arguments
151151
} in format string, but {$desc}
152+
builtin_macros_offset_of_expected_field = expected field
153+
154+
builtin_macros_offset_of_expected_two_args = expected 2 arguments

compiler/rustc_builtin_macros/src/assert/context.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,7 @@ impl<'cx, 'a> Context<'cx, 'a> {
301301
| ExprKind::If(_, _, _)
302302
| ExprKind::IncludedBytes(..)
303303
| ExprKind::InlineAsm(_)
304+
| ExprKind::OffsetOf(_, _)
304305
| ExprKind::Let(_, _, _)
305306
| ExprKind::Lit(_)
306307
| ExprKind::Loop(_, _, _)

0 commit comments

Comments
 (0)