offset_of

This commit is contained in:
DrMeepster
2022-09-11 00:37:49 -07:00
parent b92a41c676
commit 511e457c4b
71 changed files with 841 additions and 38 deletions

View File

@@ -237,6 +237,39 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
}
}
fn handle_offset_of(&mut self, expr: &'tcx hir::Expr<'tcx>) {
let data = self.typeck_results().offset_of_data();
let &(container, ref indices) =
data.get(expr.hir_id).expect("no offset_of_data for offset_of");
let mut last_did = expr.hir_id.owner.to_def_id();
let mut current_ty = container;
for &index in indices {
match current_ty.kind() {
ty::Adt(def, subst) => {
let field = &def.non_enum_variant().fields[index];
self.insert_def_id(field.did);
let field_ty = field.ty(self.tcx, subst);
last_did = field.did;
current_ty =
self.tcx.normalize_erasing_regions(self.tcx.param_env(field.did), field_ty);
}
// we don't need to mark tuple fields as live,
// but we may need to mark subfields
ty::Tuple(tys) => {
current_ty = self.tcx.normalize_erasing_regions(
self.tcx.param_env(last_did),
tys[index.as_usize()],
);
}
_ => span_bug!(expr.span, "named field access on non-ADT"),
}
}
}
fn mark_live_symbols(&mut self) {
let mut scanned = LocalDefIdSet::default();
while let Some(id) = self.worklist.pop() {
@@ -405,6 +438,9 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
hir::ExprKind::Closure(cls) => {
self.insert_def_id(cls.def_id.to_def_id());
}
hir::ExprKind::OffsetOf(..) => {
self.handle_offset_of(expr);
}
_ => (),
}