diff options
| author | George Bateman <george.bateman16@gmail.com> | 2023-08-15 20:10:45 +0100 |
|---|---|---|
| committer | George Bateman <george.bateman16@gmail.com> | 2023-10-31 23:25:54 +0000 |
| commit | e936416a8d3cfb501504f00d7250d5b595fed244 (patch) | |
| tree | c0dd8196372db8a77ae1a90d38d87b630658e90e /compiler/rustc_passes | |
| parent | 9d83ac217957eece2189eccf4a7232caec7232ee (diff) | |
| download | rust-e936416a8d3cfb501504f00d7250d5b595fed244.tar.gz rust-e936416a8d3cfb501504f00d7250d5b595fed244.zip | |
Support enum variants in offset_of!
Diffstat (limited to 'compiler/rustc_passes')
| -rw-r--r-- | compiler/rustc_passes/src/dead.rs | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 87d4850b475..3b4f6a618c8 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -248,6 +248,8 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } fn handle_offset_of(&mut self, expr: &'tcx hir::Expr<'tcx>) { + use rustc_target::abi::OffsetOfIdx::*; + 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"); @@ -256,11 +258,23 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { let param_env = self.tcx.param_env(body_did); let mut current_ty = container; + let mut indices = indices.into_iter(); + + while let Some(&index) = indices.next() { + match (current_ty.kind(), index) { + (ty::Adt(def, subst), Field(field)) if !def.is_enum() => { + let field = &def.non_enum_variant().fields[field]; - 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); + + current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty); + } + (ty::Adt(def, subst), Variant(variant)) if def.is_enum() => { + let Some(&Field(field)) = indices.next() else { + span_bug!(expr.span, "variant must be followed by field in offset_of") + }; + let field = &def.variant(variant).fields[field]; self.insert_def_id(field.did); let field_ty = field.ty(self.tcx, subst); @@ -269,11 +283,12 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } // we don't need to mark tuple fields as live, // but we may need to mark subfields - ty::Tuple(tys) => { + (ty::Tuple(tys), Field(field)) => { current_ty = - self.tcx.normalize_erasing_regions(param_env, tys[index.as_usize()]); + self.tcx.normalize_erasing_regions(param_env, tys[field.as_usize()]); } - _ => span_bug!(expr.span, "named field access on non-ADT"), + (_, Field(_)) => span_bug!(expr.span, "named field access on non-ADT"), + (_, Variant(_)) => span_bug!(expr.span, "enum variant access on non-enum"), } } } |
