Skip to content

Commit

Permalink
Auto merge of rust-lang#106934 - DrMeepster:offset_of, r=WaffleLapkin
Browse files Browse the repository at this point in the history
Add offset_of! macro (RFC 3308)

Implements rust-lang/rfcs#3308 (tracking issue rust-lang#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)
  • Loading branch information
bors committed Apr 22, 2023
2 parents 84bab31 + 68c4776 commit 86d8f12
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 3 deletions.
3 changes: 2 additions & 1 deletion clippy_lints/src/loops/never_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,8 @@ fn never_loop_expr(expr: &Expr<'_>, ignore_ids: &mut Vec<HirId>, main_loop_id: H
| InlineAsmOperand::SymStatic { .. } => NeverLoopResult::Otherwise,
})
.fold(NeverLoopResult::Otherwise, combine_seq),
ExprKind::Yield(_, _)
ExprKind::OffsetOf(_, _)
| ExprKind::Yield(_, _)
| ExprKind::Closure { .. }
| ExprKind::Path(_)
| ExprKind::ConstBlock(_)
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/matches/significant_drop_in_scrutinee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SigDropHelper<'a, 'tcx> {
ExprKind::DropTemps(_) |
ExprKind::Err(_) |
ExprKind::InlineAsm(_) |
ExprKind::OffsetOf(_, _) |
ExprKind::Let(_) |
ExprKind::Lit(_) |
ExprKind::Loop(_, _, _, _) |
Expand Down
4 changes: 4 additions & 0 deletions clippy_lints/src/utils/author.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,10 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
kind!("InlineAsm(_)");
out!("// unimplemented: `ExprKind::InlineAsm` is not further destructured at the moment");
},
ExprKind::OffsetOf(container, ref fields) => {
bind!(self, container, fields);
kind!("OffsetOf({container}, {fields})");
}
ExprKind::Struct(qpath, fields, base) => {
bind!(self, qpath, fields);
opt_bind!(self, base);
Expand Down
3 changes: 2 additions & 1 deletion clippy_utils/src/eager_or_lazy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
| ExprKind::AddrOf(..)
| ExprKind::Struct(..)
| ExprKind::Repeat(..)
| ExprKind::Block(Block { stmts: [], .. }, _) => (),
| ExprKind::Block(Block { stmts: [], .. }, _)
| ExprKind::OffsetOf(..) => (),

// Assignment might be to a local defined earlier, so don't eagerly evaluate.
// Blocks with multiple statements might be expensive, so don't eagerly evaluate.
Expand Down
9 changes: 9 additions & 0 deletions clippy_utils/src/hir_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ impl HirEqInterExpr<'_, '_, '_> {
(&ExprKind::Unary(l_op, le), &ExprKind::Unary(r_op, re)) => l_op == r_op && self.eq_expr(le, re),
(&ExprKind::Array(l), &ExprKind::Array(r)) => self.eq_exprs(l, r),
(&ExprKind::DropTemps(le), &ExprKind::DropTemps(re)) => self.eq_expr(le, re),
(&ExprKind::OffsetOf(l_container, ref l_fields), &ExprKind::OffsetOf(r_container, ref r_fields)) => {
self.eq_ty(l_container, r_container) && over(l_fields, r_fields, |l, r| l.name == r.name)
},
_ => false,
};
(is_eq && (!self.should_ignore(left) || !self.should_ignore(right)))
Expand Down Expand Up @@ -701,6 +704,12 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
}
}
},
ExprKind::OffsetOf(container, fields) => {
self.hash_ty(container);
for field in fields {
self.hash_name(field.name);
}
},
ExprKind::Let(Let { pat, init, ty, .. }) => {
self.hash_expr(init);
if let Some(ty) = ty {
Expand Down
2 changes: 1 addition & 1 deletion clippy_utils/src/qualify_min_const_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ fn check_rvalue<'tcx>(
))
}
},
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => Ok(()),
Rvalue::UnaryOp(_, operand) => {
let ty = operand.ty(body, tcx);
if ty.is_integral() || ty.is_bool() {
Expand Down
2 changes: 2 additions & 0 deletions clippy_utils/src/sugg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ impl<'a> Sugg<'a> {
| hir::ExprKind::Field(..)
| hir::ExprKind::Index(..)
| hir::ExprKind::InlineAsm(..)
| hir::ExprKind::OffsetOf(..)
| hir::ExprKind::ConstBlock(..)
| hir::ExprKind::Lit(..)
| hir::ExprKind::Loop(..)
Expand Down Expand Up @@ -197,6 +198,7 @@ impl<'a> Sugg<'a> {
| ast::ExprKind::ForLoop(..)
| ast::ExprKind::Index(..)
| ast::ExprKind::InlineAsm(..)
| ast::ExprKind::OffsetOf(..)
| ast::ExprKind::ConstBlock(..)
| ast::ExprKind::Lit(..)
| ast::ExprKind::IncludedBytes(..)
Expand Down
1 change: 1 addition & 0 deletions clippy_utils/src/visitors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
| ExprKind::Path(_)
| ExprKind::Continue(_)
| ExprKind::InlineAsm(_)
| ExprKind::OffsetOf(..)
| ExprKind::Err(_) => (),
}
ControlFlow::Continue(())
Expand Down

0 comments on commit 86d8f12

Please sign in to comment.