Auto merge of #106934 - DrMeepster:offset_of, r=WaffleLapkin
Add offset_of! macro (RFC 3308) Implements https://github.com/rust-lang/rfcs/pull/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)
This commit is contained in:
commit
86d8f1268a
|
@ -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(_)
|
||||
|
|
|
@ -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(_, _, _, _) |
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)))
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(..)
|
||||
|
@ -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(..)
|
||||
|
|
|
@ -662,6 +662,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>(
|
|||
| ExprKind::Path(_)
|
||||
| ExprKind::Continue(_)
|
||||
| ExprKind::InlineAsm(_)
|
||||
| ExprKind::OffsetOf(..)
|
||||
| ExprKind::Err(_) => (),
|
||||
}
|
||||
ControlFlow::Continue(())
|
||||
|
|
Loading…
Reference in New Issue