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
80a2ec49a4
83 changed files with 1355 additions and 42 deletions
|
@ -557,6 +557,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
| ExprKind::ConstBlock { .. }
|
||||
| ExprKind::StaticRef { .. }
|
||||
| ExprKind::InlineAsm { .. }
|
||||
| ExprKind::OffsetOf { .. }
|
||||
| ExprKind::Yield { .. }
|
||||
| ExprKind::ThreadLocalRef(_)
|
||||
| ExprKind::Call { .. } => {
|
||||
|
|
|
@ -481,6 +481,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}))))
|
||||
}
|
||||
|
||||
ExprKind::OffsetOf { container, fields } => {
|
||||
block.and(Rvalue::NullaryOp(NullOp::OffsetOf(fields), container))
|
||||
}
|
||||
|
||||
ExprKind::Literal { .. }
|
||||
| ExprKind::NamedConst { .. }
|
||||
| ExprKind::NonHirLiteral { .. }
|
||||
|
|
|
@ -67,7 +67,8 @@ impl Category {
|
|||
| ExprKind::Repeat { .. }
|
||||
| ExprKind::Assign { .. }
|
||||
| ExprKind::AssignOp { .. }
|
||||
| ExprKind::ThreadLocalRef(_) => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
|
||||
| ExprKind::ThreadLocalRef(_)
|
||||
| ExprKind::OffsetOf { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
|
||||
|
||||
ExprKind::ConstBlock { .. }
|
||||
| ExprKind::Literal { .. }
|
||||
|
|
|
@ -561,7 +561,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
| ExprKind::ZstLiteral { .. }
|
||||
| ExprKind::ConstParam { .. }
|
||||
| ExprKind::ThreadLocalRef(_)
|
||||
| ExprKind::StaticRef { .. } => {
|
||||
| ExprKind::StaticRef { .. }
|
||||
| ExprKind::OffsetOf { .. } => {
|
||||
debug_assert!(match Category::of(&expr.kind).unwrap() {
|
||||
// should be handled above
|
||||
Category::Rvalue(RvalueFunc::Into) => false,
|
||||
|
|
|
@ -323,6 +323,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
|
|||
| ExprKind::Box { .. }
|
||||
| ExprKind::If { .. }
|
||||
| ExprKind::InlineAsm { .. }
|
||||
| ExprKind::OffsetOf { .. }
|
||||
| ExprKind::LogicalOp { .. }
|
||||
| ExprKind::Use { .. } => {
|
||||
// We don't need to save the old value and restore it
|
||||
|
|
|
@ -664,6 +664,14 @@ impl<'tcx> Cx<'tcx> {
|
|||
line_spans: asm.line_spans,
|
||||
})),
|
||||
|
||||
hir::ExprKind::OffsetOf(_, _) => {
|
||||
let data = self.typeck_results.offset_of_data();
|
||||
let &(container, ref indices) = data.get(expr.hir_id).unwrap();
|
||||
let fields = tcx.mk_fields_from_iter(indices.iter().copied());
|
||||
|
||||
ExprKind::OffsetOf { container, fields }
|
||||
}
|
||||
|
||||
hir::ExprKind::ConstBlock(ref anon_const) => {
|
||||
let ty = self.typeck_results().node_type(anon_const.hir_id);
|
||||
let did = anon_const.def_id.to_def_id();
|
||||
|
|
|
@ -519,6 +519,19 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
|
|||
self.print_inline_asm_expr(&**expr, depth_lvl + 2);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
OffsetOf { container, fields } => {
|
||||
print_indented!(self, "OffsetOf {", depth_lvl);
|
||||
print_indented!(self, format!("container: {:?}", container), depth_lvl + 1);
|
||||
print_indented!(self, "fields: [", depth_lvl + 1);
|
||||
|
||||
for field in fields.iter() {
|
||||
print_indented!(self, format!("{:?}", field), depth_lvl + 2);
|
||||
print_indented!(self, ",", depth_lvl + 1);
|
||||
}
|
||||
|
||||
print_indented!(self, "]", depth_lvl + 1);
|
||||
print_indented!(self, "}", depth_lvl);
|
||||
}
|
||||
ThreadLocalRef(def_id) => {
|
||||
print_indented!(self, "ThreadLocalRef {", depth_lvl);
|
||||
print_indented!(self, format!("def_id: {:?}", def_id), depth_lvl + 1);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue