Skip to content

Commit 7aa5f39

Browse files
author
Lukas Markeffsky
committed
add helper methods for accessing struct tail
1 parent e3de14e commit 7aa5f39

File tree

9 files changed

+31
-34
lines changed

9 files changed

+31
-34
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -981,7 +981,7 @@ fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: b
981981
// intermediate types must be sized.
982982
let needs_drop_copy = || {
983983
packed && {
984-
let ty = tcx.type_of(variant.fields.raw.last().unwrap().did).subst_identity();
984+
let ty = tcx.type_of(variant.tail().did).subst_identity();
985985
let ty = tcx.erase_regions(ty);
986986
if ty.has_infer() {
987987
tcx.sess

compiler/rustc_hir_typeck/src/cast.rs

+6-8
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
103103
Ok(match *t.kind() {
104104
ty::Slice(_) | ty::Str => Some(PointerKind::Length),
105105
ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())),
106-
ty::Adt(def, substs) if def.is_struct() => {
107-
match def.non_enum_variant().fields.raw.last() {
108-
None => Some(PointerKind::Thin),
109-
Some(f) => {
110-
let field_ty = self.field_ty(span, f, substs);
111-
self.pointer_kind(field_ty, span)?
112-
}
106+
ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().tail_opt() {
107+
None => Some(PointerKind::Thin),
108+
Some(f) => {
109+
let field_ty = self.field_ty(span, f, substs);
110+
self.pointer_kind(field_ty, span)?
113111
}
114-
}
112+
},
115113
ty::Tuple(fields) => match fields.last() {
116114
None => Some(PointerKind::Thin),
117115
Some(&f) => self.pointer_kind(f, span)?,

compiler/rustc_middle/src/ty/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -2028,6 +2028,22 @@ impl VariantDef {
20282028

20292029
&self.fields[FieldIdx::from_u32(0)]
20302030
}
2031+
2032+
/// Returns the last field in this variant, if present.
2033+
#[inline]
2034+
pub fn tail_opt(&self) -> Option<&FieldDef> {
2035+
self.fields.raw.last()
2036+
}
2037+
2038+
/// Returns the last field in this variant.
2039+
///
2040+
/// # Panics
2041+
///
2042+
/// Panics, if the variant has no fields.
2043+
#[inline]
2044+
pub fn tail(&self) -> &FieldDef {
2045+
self.tail_opt().expect("expected unsized ADT to have a tail field")
2046+
}
20312047
}
20322048

20332049
impl PartialEq for VariantDef {

compiler/rustc_middle/src/ty/util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ impl<'tcx> TyCtxt<'tcx> {
230230
if !def.is_struct() {
231231
break;
232232
}
233-
match def.non_enum_variant().fields.raw.last() {
233+
match def.non_enum_variant().tail_opt() {
234234
Some(field) => {
235235
f();
236236
ty = field.ty(self, substs);
@@ -304,7 +304,7 @@ impl<'tcx> TyCtxt<'tcx> {
304304
(&ty::Adt(a_def, a_substs), &ty::Adt(b_def, b_substs))
305305
if a_def == b_def && a_def.is_struct() =>
306306
{
307-
if let Some(f) = a_def.non_enum_variant().fields.raw.last() {
307+
if let Some(f) = a_def.non_enum_variant().tail_opt() {
308308
a = f.ty(self, a_substs);
309309
b = f.ty(self, b_substs);
310310
} else {

compiler/rustc_trait_selection/src/solve/project_goals.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
366366
}
367367

368368
ty::Adt(def, substs) if def.is_struct() => {
369-
match def.non_enum_variant().fields.raw.last() {
369+
match def.non_enum_variant().tail_opt() {
370370
None => tcx.types.unit,
371371
Some(field_def) => {
372372
let self_ty = field_def.ty(tcx, substs);

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -398,12 +398,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
398398
return Err(NoSolution);
399399
}
400400

401-
let tail_field = a_def
402-
.non_enum_variant()
403-
.fields
404-
.raw
405-
.last()
406-
.expect("expected unsized ADT to have a tail field");
401+
let tail_field = a_def.non_enum_variant().tail();
407402
let tail_field_ty = tcx.type_of(tail_field.did);
408403

409404
let a_tail_ty = tail_field_ty.subst(tcx, a_substs);

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+1-6
Original file line numberDiff line numberDiff line change
@@ -1125,12 +1125,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11251125
return Err(Unimplemented);
11261126
}
11271127

1128-
let tail_field = def
1129-
.non_enum_variant()
1130-
.fields
1131-
.raw
1132-
.last()
1133-
.expect("expected unsized ADT to have a tail field");
1128+
let tail_field = def.non_enum_variant().tail();
11341129
let tail_field_ty = tcx.type_of(tail_field.did);
11351130

11361131
// Extract `TailField<T>` and `TailField<U>` from `Struct<T>` and `Struct<U>`,

compiler/rustc_ty_utils/src/layout.rs

+2-9
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ fn layout_of_uncached<'tcx>(
480480
.any(|(i, v)| v.discr != ty::VariantDiscr::Relative(i.as_u32()));
481481

482482
let maybe_unsized = def.is_struct()
483-
&& def.non_enum_variant().fields.raw.last().is_some_and(|last_field| {
483+
&& def.non_enum_variant().tail_opt().is_some_and(|last_field| {
484484
let param_env = tcx.param_env(def.did());
485485
!tcx.type_of(last_field.did).subst_identity().is_sized(tcx, param_env)
486486
});
@@ -502,14 +502,7 @@ fn layout_of_uncached<'tcx>(
502502
// If the struct tail is sized and can be unsized, check that unsizing doesn't move the fields around.
503503
if cfg!(debug_assertions)
504504
&& maybe_unsized
505-
&& def
506-
.non_enum_variant()
507-
.fields
508-
.raw
509-
.last()
510-
.unwrap()
511-
.ty(tcx, substs)
512-
.is_sized(tcx, cx.param_env)
505+
&& def.non_enum_variant().tail().ty(tcx, substs).is_sized(tcx, cx.param_env)
513506
{
514507
let mut variants = variants;
515508
let tail_replacement = cx.layout_of(Ty::new_slice(tcx, tcx.types.u8)).unwrap();

compiler/rustc_ty_utils/src/ty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn adt_sized_constraint(tcx: TyCtxt<'_>, def_id: DefId) -> &[Ty<'_>] {
103103
let result = tcx.mk_type_list_from_iter(
104104
def.variants()
105105
.iter()
106-
.filter_map(|v| v.fields.raw.last())
106+
.filter_map(|v| v.tail_opt())
107107
.flat_map(|f| sized_constraint_for_ty(tcx, def, tcx.type_of(f.did).subst_identity())),
108108
);
109109

0 commit comments

Comments
 (0)