offset_of
This commit is contained in:
@@ -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);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user