diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index c2c3f5bc79ed1..7e555926252f7 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -1020,7 +1020,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { return; }; let mut sugg = vec![]; - for field in &variant.fields { + for field in variant.fields() { // In practice unless there are more than one field with the same type, we'll be // suggesting a single field at a type, because we don't aggregate multiple borrow // checker errors involving the functional record update sytnax into a single one. @@ -1034,7 +1034,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { } let (span, sugg) = match fields { [.., last] => ( - if final_field_count == variant.fields.len() { + if final_field_count == variant.fields().len() { // We'll remove the `..base` as there aren't any fields left. last.span.shrink_to_hi().with_hi(base.span.hi()) } else { @@ -1045,7 +1045,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { // Account for no fields in suggestion span. [] => ( expr.span.with_lo(struct_qpath.span().hi()), - if final_field_count == variant.fields.len() { + if final_field_count == variant.fields().len() { // We'll remove the `..base` as there aren't any fields left. format!(" {{ {} }}", sugg.join(", ")) } else { @@ -1185,7 +1185,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { && def.did().as_local().is_some() && def.variants().iter().all(|variant| { variant - .fields + .fields() .iter() .all(|field| self.implements_clone(field.ty(self.infcx.tcx, args))) }) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 4567a014fe83d..e3b9b55357bdd 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -361,7 +361,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> { if !including_tuple_field.0 && variant.ctor_kind() == Some(CtorKind::Fn) { return None; } - Some(variant.fields[field].name.to_string()) + Some(variant.fields()[field].name.to_string()) } ty::Tuple(_) => Some(field.index().to_string()), ty::Ref(_, ty, _) | ty::RawPtr(ty, _) => { diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index db4b5209145f0..885667e0f39ea 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -845,10 +845,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { }, }; - if let Some(field) = variant.fields.get(field) { + if let Some(field) = variant.fields().get(field) { Ok(self.cx.normalize(field.ty(tcx, args), location)) } else { - Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) + Err(FieldAccessError::OutOfRange { field_count: variant.fields().len() }) } } } @@ -1826,10 +1826,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let def = tcx.adt_def(adt_did); let variant = &def.variant(variant_index); let adj_field_index = active_field_index.unwrap_or(field_index); - if let Some(field) = variant.fields.get(adj_field_index) { + if let Some(field) = variant.fields().get(adj_field_index) { Ok(self.normalize(field.ty(tcx, args), location)) } else { - Err(FieldAccessError::OutOfRange { field_count: variant.fields.len() }) + Err(FieldAccessError::OutOfRange { field_count: variant.fields().len() }) } } AggregateKind::Closure(_, args) => { diff --git a/compiler/rustc_codegen_cranelift/src/inline_asm.rs b/compiler/rustc_codegen_cranelift/src/inline_asm.rs index c88230c936056..72e2666189e00 100644 --- a/compiler/rustc_codegen_cranelift/src/inline_asm.rs +++ b/compiler/rustc_codegen_cranelift/src/inline_asm.rs @@ -917,7 +917,7 @@ fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option { - let fields = &adt.non_enum_variant().fields; + let fields = &adt.non_enum_variant().fields(); let ty = fields[FieldIdx::from_u32(1)].ty(fx.tcx, args); let ty::Adt(ty, args) = ty.kind() else { unreachable!("expected first field of `MaybeUninit` to be an ADT") @@ -926,7 +926,7 @@ fn asm_clif_type<'tcx>(fx: &FunctionCx<'_, '_, 'tcx>, ty: Ty<'tcx>) -> Option( // Fields: |cx, owner| { variant_def - .fields + .fields() .iter() .enumerate() .map(|(i, f)| { @@ -1222,7 +1222,7 @@ fn build_union_type_di_node<'ll, 'tcx>( // Fields: |cx, owner| { variant_def - .fields + .fields() .iter() .enumerate() .map(|(i, f)| { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs index 2b00bb14593e4..b543108778588 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs @@ -274,7 +274,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>( .map(|field_index| { let field_name = if variant_def.ctor_kind() != Some(CtorKind::Fn) { // Fields have names - let field = &variant_def.fields[FieldIdx::from_usize(field_index)]; + let field = &variant_def.fields()[FieldIdx::from_usize(field_index)]; Cow::from(field.name.as_str()) } else { // Tuple-like diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 137f14fe706cc..b6f52d4042772 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -273,7 +273,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) => { assert_eq!(def_a, def_b); // implies same number of fields - for i in def_a.variant(FIRST_VARIANT).fields.indices() { + for i in def_a.variant(FIRST_VARIANT).fields().indices() { let src_f = src.project_field(bx, i.as_usize()); let dst_f = dst.project_field(bx, i.as_usize()); diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 4ae4816e33ab9..8bdbc12fdb0d8 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -63,7 +63,7 @@ pub(crate) fn try_destructure_mir_constant_for_user_output<'tcx>( ty::Adt(def, _) => { let variant = ecx.read_discriminant(&op).ok()?; let down = ecx.project_downcast(&op, variant).ok()?; - (def.variants()[variant].fields.len(), Some(variant), down) + (def.variants()[variant].fields().len(), Some(variant), down) } ty::Tuple(args) => (args.len(), None, op), _ => bug!("cannot destructure mir constant {:?}", val), diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 2e8ad445cf5e8..86bb5d9b175da 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -162,7 +162,7 @@ fn const_to_valtree_inner<'tcx>( } let variant = ecx.read_discriminant(place)?; - branches(ecx, place, def.variant(variant).fields.len(), def.is_enum().then_some(variant), num_nodes) + branches(ecx, place, def.variant(variant).fields().len(), def.is_enum().then_some(variant), num_nodes) } ty::Never diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index 7fea061766666..af8e22487535a 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -269,7 +269,9 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { match layout.variants { Variants::Single { index } => { // Inside a variant - PathElem::Field(def.variant(index).fields[FieldIdx::from_usize(field)].name) + PathElem::Field( + def.variant(index).fields()[FieldIdx::from_usize(field)].name, + ) } Variants::Multiple { .. } => bug!("we handled variants above"), } @@ -277,7 +279,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> { // other ADTs ty::Adt(def, _) => { - PathElem::Field(def.non_enum_variant().fields[FieldIdx::from_usize(field)].name) + PathElem::Field(def.non_enum_variant().fields()[FieldIdx::from_usize(field)].name) } // arrays/slices diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs index 71c057e549b41..8d81c9cbaa3f5 100644 --- a/compiler/rustc_const_eval/src/interpret/visitor.rs +++ b/compiler/rustc_const_eval/src/interpret/visitor.rs @@ -197,7 +197,7 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized { // could be a problem for `ImmTy` (see layout_sanity_check): // - variant.size == Size::ZERO: works fine because `ImmTy::offset` has a special case for // zero-sized layouts. - // - variant.fields.count() == 0: works fine because `ImmTy::offset` has a special case for + // - variant.fields().count() == 0: works fine because `ImmTy::offset` has a special case for // zero-field aggregates. // - variant.abi.is_uninhabited(): triggers UB in `read_discriminant` so we never get here. let inner = self.ecx().project_downcast(v, idx)?; diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f93777eda529e..b9cadd36ad30a 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -102,7 +102,7 @@ fn check_unnamed_fields(tcx: TyCtxt<'_>, def: ty::AdtDef<'_>) { let adt_kind = def.descr(); let span = tcx.def_span(def.did()); let unnamed_fields = variant - .fields + .fields() .iter() .filter(|f| f.is_unnamed()) .map(|f| { @@ -122,7 +122,7 @@ fn check_unnamed_fields(tcx: TyCtxt<'_>, def: ty::AdtDef<'_>) { }); } } - for field in variant.fields.iter().filter(|f| f.is_unnamed()) { + for field in variant.fields().iter().filter(|f| f.is_unnamed()) { let field_ty = tcx.type_of(field.did).instantiate_identity(); if let Some(adt) = field_ty.ty_adt_def() && !adt.is_enum() @@ -176,7 +176,7 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b } let param_env = tcx.param_env(item_def_id); - for field in &def.non_enum_variant().fields { + for field in def.non_enum_variant().fields() { let Ok(field_ty) = tcx.try_normalize_erasing_regions(param_env, field.ty(tcx, args)) else { tcx.dcx().span_delayed_bug(span, "could not normalize field type"); @@ -647,7 +647,8 @@ fn is_enum_of_nonnullable_ptr<'tcx>( let [var_one, var_two] = &adt_def.variants().raw[..] else { return false; }; - let (([], [field]) | ([field], [])) = (&var_one.fields.raw[..], &var_two.fields.raw[..]) else { + let (([], [field]) | ([field], [])) = (&var_one.fields().raw[..], &var_two.fields().raw[..]) + else { return false; }; matches!(field.ty(tcx, args).kind(), ty::FnPtr(..) | ty::Ref(..)) @@ -1059,7 +1060,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) { if let ty::Adt(def, args) = t.kind() && def.is_struct() { - let fields = &def.non_enum_variant().fields; + let fields = &def.non_enum_variant().fields(); if fields.is_empty() { struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit(); return; @@ -1201,7 +1202,7 @@ pub(super) fn check_packed_inner( } stack.push(def_id); - for field in &def.non_enum_variant().fields { + for field in def.non_enum_variant().fields() { if let ty::Adt(def, _) = field.ty(tcx, args).kind() && !stack.contains(&def.did()) && let Some(mut defs) = check_packed_inner(tcx, def.did(), stack) diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs index 2e965c59ebb53..44c4bf5f4a735 100644 --- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs +++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs @@ -69,7 +69,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::FnPtr(_) => Some(asm_ty_isize), ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize), ty::Adt(adt, args) if adt.repr().simd() => { - let fields = &adt.non_enum_variant().fields; + let fields = &adt.non_enum_variant().fields(); let elem_ty = fields[FieldIdx::ZERO].ty(self.tcx, args); let (size, ty) = match elem_ty.kind() { @@ -139,7 +139,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty::Never if is_input => return None, _ if ty.references_error() => return None, ty::Adt(adt, args) if self.tcx.is_lang_item(adt.did(), LangItem::MaybeUninit) => { - let fields = &adt.non_enum_variant().fields; + let fields = &adt.non_enum_variant().fields(); let ty = fields[FieldIdx::from_u32(1)].ty(self.tcx, args); // FIXME: Are we just trying to map to the `T` in `MaybeUninit`? // If so, just get it from the args. @@ -150,7 +150,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> { ty.is_manually_drop(), "expected first field of `MaybeUninit` to be `ManuallyDrop`" ); - let fields = &ty.non_enum_variant().fields; + let fields = &ty.non_enum_variant().fields(); let ty = fields[FieldIdx::ZERO].ty(self.tcx, args); self.get_asm_ty(ty) } diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a0eede31eb07f..9d932fad3c9b0 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1077,7 +1077,7 @@ fn check_type_defn<'tcx>( for variant in variants.iter() { // All field types must be well-formed. - for field in &variant.fields { + for field in variant.fields_checked()? { let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = tcx.hir_node_by_def_id(field_id).expect_field(); @@ -1104,12 +1104,12 @@ fn check_type_defn<'tcx>( } }; // All fields (except for possibly the last) should be sized. - let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy(); + let all_sized = all_sized || variant.fields().is_empty() || needs_drop_copy(); let unsized_len = if all_sized { 0 } else { 1 }; for (idx, field) in - variant.fields.raw[..variant.fields.len() - unsized_len].iter().enumerate() + variant.fields().raw[..variant.fields().len() - unsized_len].iter().enumerate() { - let last = idx == variant.fields.len() - 1; + let last = idx == variant.fields().len() - 1; let field_id = field.did.expect_local(); let hir::FieldDef { ty: hir_ty, .. } = tcx.hir_node_by_def_id(field_id).expect_field(); diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs index 61adb7a3cbaeb..6fa0691fb6887 100644 --- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs +++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs @@ -213,7 +213,7 @@ fn visit_implementation_of_dispatch_from_dyn(checker: &Checker<'_>) -> Result<() res = Err(tcx.dcx().emit_err(errors::DispatchFromDynRepr { span })); } - let fields = &def_a.non_enum_variant().fields; + let fields = &def_a.non_enum_variant().fields(); let coerced_fields = fields .iter() @@ -411,7 +411,7 @@ pub fn coerce_unsized_info<'tcx>( // conversion). This will work out because `U: // Unsize`, and we have a builtin rule that `*mut // U` can be coerced to `*mut V` if `U: Unsize`. - let fields = &def_a.non_enum_variant().fields; + let fields = &def_a.non_enum_variant().fields(); let diff_fields = fields .iter_enumerated() .filter_map(|(i, f)| { diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 843e4d41e001e..34c2d2e1fb95f 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -867,7 +867,7 @@ fn lower_enum_variant_types(tcx: TyCtxt<'_>, def_id: DefId) { .unwrap_or(wrapped_discr), ); - for f in &variant.fields { + for f in variant.fields() { tcx.ensure().generics_of(f.did); tcx.ensure().type_of(f.did); tcx.ensure().predicates_of(f.did); @@ -886,7 +886,7 @@ fn find_field(tcx: TyCtxt<'_>, (def_id, ident): (DefId, Ident)) -> Option Some(guard.clone()), + _ => None, + }; + ty::VariantDef::new( ident.name, variant_did.map(LocalDefId::to_def_id), diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bd5e5294983d2..5ca63c6dc5e54 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1679,7 +1679,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let adt_kind = adt.adt_kind(); let mut remaining_fields = variant - .fields + .fields() .iter_enumerated() .map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field))) .collect::>(); @@ -1688,7 +1688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut error_happened = false; - if variant.fields.len() != remaining_fields.len() { + if variant.fields().len() != remaining_fields.len() { // Some field is defined more than once. Make sure we don't try to // instantiate this struct in static/const context. let guar = @@ -1788,7 +1788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // needs constrained to be compatible with the struct // type we expect from the expectation value. let fru_tys = variant - .fields + .fields() .iter() .map(|f| { let fru_ty = self @@ -1870,7 +1870,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); match adt_ty.kind() { ty::Adt(adt, args) if adt.is_struct() => variant - .fields + .fields() .iter() .map(|f| self.normalize(expr.span, f.ty(self.tcx, args))) .collect(), @@ -1885,7 +1885,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else if adt_kind != AdtKind::Union && !remaining_fields.is_empty() { debug!(?remaining_fields); let private_fields: Vec<&ty::FieldDef> = variant - .fields + .fields() .iter() .filter(|field| !field.vis.is_accessible_from(tcx.parent_module(expr.hir_id), tcx)) .collect(); @@ -1992,7 +1992,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [range_start, range_end], _) = last_expr_field.expr.kind && let variant_field = - variant.fields.iter().find(|field| field.ident(self.tcx) == last_expr_field.ident) + variant.fields().iter().find(|field| field.ident(self.tcx) == last_expr_field.ident) && let range_def_id = self.tcx.lang_items().range_struct() && variant_field .and_then(|field| field.ty(self.tcx, args).ty_adt_def()) @@ -2299,7 +2299,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { skip_fields: &[hir::ExprField<'_>], ) -> Vec { variant - .fields + .fields() .iter() .filter(|field| { skip_fields.iter().all(|&skip| skip.ident.name != field.name) @@ -2347,7 +2347,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut index = None; while let Some(idx) = self.tcx.find_field((adt_def.did(), ident)) { let &mut first_idx = index.get_or_insert(idx); - let field = &adt_def.non_enum_variant().fields[idx]; + let field = &adt_def.non_enum_variant().fields()[idx]; let field_ty = self.field_ty(expr.span, field, args); if let Some(ty) = last_ty { nested_fields.push((ty, idx)); @@ -2520,7 +2520,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(field_ident.span, "unknown field"); return; } - if !def.non_enum_variant().fields.iter().any(|field| field.ident(self.tcx) == field_ident) { + if !def.non_enum_variant().fields().iter().any(|field| field.ident(self.tcx) == field_ident) + { err.span_label(field_ident.span, "unknown field"); return; } @@ -2547,6 +2548,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}", ident, base, expr, base_ty ); + + for (ty, _) in self.autoderef(expr.span, base_ty) { + if let ty::Adt(def, _) = ty.kind() + && !def.is_enum() + { + let variant = def.non_enum_variant(); + if let Err(reported) = variant.fields_checked() { + return reported; + } + } + } + let mut err = self.no_such_field_err(ident, base_ty, base.hir_id); match *base_ty.peel_refs().kind() { @@ -2572,7 +2585,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let ty::Adt(def, _) = output_ty.kind() && !def.is_enum() { - def.non_enum_variant().fields.iter().any(|field| { + def.non_enum_variant().fields().iter().any(|field| { field.ident(self.tcx) == ident && field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx) }) @@ -2682,7 +2695,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .iter() .next() .unwrap() - .fields + .fields() .iter() .any(|f| f.ident(self.tcx) == field) { @@ -2874,7 +2887,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match base_t.kind() { ty::Adt(base_def, args) if !base_def.is_enum() => { let tcx = self.tcx; - let fields = &base_def.non_enum_variant().fields; + let fields = &base_def.non_enum_variant().fields(); // Some struct, e.g. some that impl `Deref`, have all private fields // because you're expected to deref them to access the _real_ fields. // This, for example, will help us suggest accessing a field through a `Box`. @@ -3349,7 +3362,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, block); let Some((subindex, field)) = variant - .fields + .fields() .iter_enumerated() .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident) else { @@ -3390,7 +3403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (ident, def_scope) = self.tcx.adjust_ident_and_get_scope(field, container_def.did(), block); - let fields = &container_def.non_enum_variant().fields; + let fields = &container_def.non_enum_variant().fields(); if let Some((index, field)) = fields .iter_enumerated() .find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == ident) diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 193dbbbcdf44d..616fee04b3545 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -714,7 +714,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() { ty::Adt(adt, args) if adt.is_struct() => { // Consume those fields of the with expression that are needed. - for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() { + for (f_index, with_field) in adt.non_enum_variant().fields().iter_enumerated() { let is_mentioned = fields.iter().any(|f| { self.cx.typeck_results().opt_field_index(f.hir_id) == Some(f_index) }); @@ -1555,7 +1555,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx ) -> Result { let ty = self.cx.typeck_results().node_type(pat_hir_id); match self.cx.try_structurally_resolve_type(span, ty).kind() { - ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()), + ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields().len()), _ => { self.cx .tcx() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs index f7abba357064d..5a1350a8eda28 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs @@ -384,7 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let identity_args = ty::GenericArgs::identity_for_item(self.tcx, def_id); let fields_referencing_param: Vec<_> = def .variant_with_id(variant_def_id) - .fields + .fields() .iter() .filter(|field| { let field_ty = field.ty(self.tcx, identity_args); @@ -880,7 +880,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let Some((field_index, field_type)) = is_iterator_singleton( in_ty_adt .variant_with_id(variant_def_id) - .fields + .fields() .iter() .map(|field| field.ty(self.tcx, *in_ty_adt_generic_args)) .enumerate() diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index fca0a3e195d77..a999886ce1b8b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2157,7 +2157,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .variants() .iter() .filter(|variant| { - variant.fields.len() == 1 + variant.fields().len() == 1 }) .filter_map(|variant| { let sole_field = &variant.single_field(); diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs index 0389c06c3123f..5ce2c5f22d4c2 100644 --- a/compiler/rustc_hir_typeck/src/intrinsicck.rs +++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs @@ -20,15 +20,15 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { let one = VariantIdx::new(1); let zero = VariantIdx::ZERO; - if def.variant(zero).fields.is_empty() { + if def.variant(zero).fields().is_empty() { data_idx = one; - } else if def.variant(one).fields.is_empty() { + } else if def.variant(one).fields().is_empty() { data_idx = zero; } else { return ty; } - if def.variant(data_idx).fields.len() == 1 { + if def.variant(data_idx).fields().len() == 1 { return def.variant(data_idx).single_field().ty(tcx, args); } } diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index dba3edbc1d722..acb16265de87a 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2248,7 +2248,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::Adt(def, args) if !def.is_enum() => { let variant = &def.non_enum_variant(); tcx.find_field_index(item_name, variant).map(|index| { - let field = &variant.fields[index]; + let field = &variant.fields()[index]; let field_ty = field.ty(tcx, args); (field, field_ty) }) @@ -2658,7 +2658,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .variants() .iter() .flat_map(|variant| { - let [field] = &variant.fields.raw[..] else { + let [field] = &variant.fields().raw[..] else { return None; }; let field_ty = field.ty(tcx, args); diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index be526e1c26c4c..8976ad513b97b 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -1233,19 +1233,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let had_err = diag.map_err(|diag| diag.emit()); // Type-check subpatterns. - if subpats.len() == variant.fields.len() - || subpats.len() < variant.fields.len() && ddpos.as_opt_usize().is_some() + if subpats.len() == variant.fields().len() + || subpats.len() < variant.fields().len() && ddpos.as_opt_usize().is_some() { let ty::Adt(_, args) = pat_ty.kind() else { bug!("unexpected pattern type {:?}", pat_ty); }; - for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields.len(), ddpos) { - let field = &variant.fields[FieldIdx::from_usize(i)]; + for (i, subpat) in subpats.iter().enumerate_and_adjust(variant.fields().len(), ddpos) { + let field = &variant.fields()[FieldIdx::from_usize(i)]; let field_ty = self.field_ty(subpat.span, field, args); self.check_pat(subpat, field_ty, pat_info); self.tcx.check_stability( - variant.fields[FieldIdx::from_usize(i)].did, + variant.fields()[FieldIdx::from_usize(i)].did, Some(pat.hir_id), subpat.span, None, @@ -1261,7 +1261,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { res, qpath, subpats, - &variant.fields.raw, + &variant.fields().raw, expected, had_err, ); @@ -1484,7 +1484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Index the struct fields' types. let field_map = variant - .fields + .fields() .iter_enumerated() .map(|(i, field)| (field.ident(self.tcx).normalize_to_macros_2_0(), (i, field))) .collect::>(); @@ -1525,13 +1525,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let mut unmentioned_fields = variant - .fields + .fields_checked()? .iter() .map(|field| (field, field.ident(self.tcx).normalize_to_macros_2_0())) .filter(|(_, ident)| !used_fields.contains_key(ident)) .collect::>(); - let inexistent_fields_err = if !(inexistent_fields.is_empty() || variant.is_recovered()) + let inexistent_fields_err = if !inexistent_fields.is_empty() && !inexistent_fields.iter().any(|field| field.ident.name == kw::Underscore) { Some(self.error_inexistent_fields( @@ -1820,14 +1820,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "tuple variant `{}` written as struct variant", path ); - let (sugg, appl) = if fields.len() == variant.fields.len() { + let (sugg, appl) = if fields.len() == variant.fields().len() { ( self.get_suggested_tuple_struct_pattern(fields, variant), Applicability::MachineApplicable, ) } else { ( - variant.fields.iter().map(|_| "_").collect::>().join(", "), + variant.fields().iter().map(|_| "_").collect::>().join(", "), Applicability::MaybeIncorrect, ) }; @@ -1848,7 +1848,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { variant: &VariantDef, ) -> String { let variant_field_idents = - variant.fields.iter().map(|f| f.ident(self.tcx)).collect::>(); + variant.fields().iter().map(|f| f.ident(self.tcx)).collect::>(); fields .iter() .map(|field| { diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs index 466397817dae1..316c75164c01b 100644 --- a/compiler/rustc_hir_typeck/src/upvar.rs +++ b/compiler/rustc_hir_typeck/src/upvar.rs @@ -1590,7 +1590,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ProjectionKind::Field(..) )) ); - def.variants().get(FIRST_VARIANT).unwrap().fields.iter_enumerated().any( + def.variants().get(FIRST_VARIANT).unwrap().fields().iter_enumerated().any( |(i, field)| { let paths_using_field = captured_by_move_projs .iter() diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs index 13b145296a7c9..c65b5b4b58f05 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs @@ -93,7 +93,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { .variants() .iter() .filter(|variant| { - variant.fields.len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) + variant.fields().len() == 1 && variant.ctor_kind() == Some(CtorKind::Fn) }) .filter_map(|variant| { let sole_field = &variant.single_field(); @@ -255,7 +255,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { if let Some((name, ty)) = expected_def .non_enum_variant() - .fields + .fields() .iter() .filter(|field| field.vis.is_accessible_from(field.did, self.tcx)) .map(|field| (field.name, field.ty(self.tcx, expected_args))) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 79c8046f9b741..bb7e3cb11b1ec 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2420,7 +2420,7 @@ impl<'tcx> LateLintPass<'tcx> for InvalidValue { descr: &str, init: InitKind, ) -> Option { - let mut field_err = variant.fields.iter().find_map(|field| { + let mut field_err = variant.fields().iter().find_map(|field| { ty_find_init_error(cx, field.ty(cx.tcx, args), init).map(|mut err| { if !field.did.is_local() { err diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index 5da1cbc2283b6..94ec89cdc7828 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -296,8 +296,8 @@ fn structurally_same_type_impl<'tcx>( } // Grab a flattened representation of all fields. - let a_fields = a_def.variants().iter().flat_map(|v| v.fields.iter()); - let b_fields = b_def.variants().iter().flat_map(|v| v.fields.iter()); + let a_fields = a_def.variants().iter().flat_map(|v| v.fields().iter()); + let b_fields = b_def.variants().iter().flat_map(|v| v.fields().iter()); // Perform a structural comparison for each field. a_fields.eq_by( diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index f3a904022e9ed..d8883bbb7845f 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1013,7 +1013,7 @@ pub fn transparent_newtype_field<'a, 'tcx>( variant: &'a ty::VariantDef, ) -> Option<&'a ty::FieldDef> { let param_env = tcx.param_env(variant.def_id); - variant.fields.iter().find(|field| { + variant.fields().iter().find(|field| { let field_ty = tcx.type_of(field.did).instantiate_identity(); let is_1zst = tcx.layout_of(param_env.and(field_ty)).is_ok_and(|layout| layout.is_1zst()); !is_1zst @@ -1141,7 +1141,7 @@ pub(crate) fn repr_nullable_ptr<'tcx>( debug!("is_repr_nullable_ptr(tcx, ty = {:?})", ty); if let ty::Adt(ty_def, args) = ty.kind() { let field_ty = match &ty_def.variants().raw[..] { - [var_one, var_two] => match (&var_one.fields.raw[..], &var_two.fields.raw[..]) { + [var_one, var_two] => match (&var_one.fields().raw[..], &var_two.fields().raw[..]) { ([], [field]) | ([field], []) => field.ty(tcx, args), ([field1], [field2]) => { if !tcx.features().result_ffi_guarantees { @@ -1263,8 +1263,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; // We can't completely trust `repr(C)` markings, so make sure the fields are actually safe. - let mut all_phantom = !variant.fields.is_empty(); - for field in &variant.fields { + let mut all_phantom = !variant.fields().is_empty(); + for field in variant.fields() { all_phantom &= match self.check_field_type_for_ffi(cache, field, args) { FfiSafe => false, // `()` fields are FFI-safe! @@ -1346,7 +1346,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { }; } - if def.non_enum_variant().fields.is_empty() { + if def.non_enum_variant().fields().is_empty() { return FfiUnsafe { ty, reason: if def.is_struct() { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 83b41e0540edf..0ba9b940eed10 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1133,7 +1133,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { .collect(), adt_kind, parent_did, - false, + None, data.is_non_exhaustive, // FIXME: unnamed fields in crate metadata is unimplemented yet. false, diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 209316ca20fdb..11a381af22cbd 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1557,7 +1557,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; record!(self.tables.variant_data[variant.def_id] <- data); - record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields.iter().map(|f| { + record_array!(self.tables.associated_item_or_field_def_ids[variant.def_id] <- variant.fields().iter().map(|f| { assert!(f.did.is_local()); f.did.index })); diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs index 82625ae3d474e..4147c120ef7ac 100644 --- a/compiler/rustc_middle/src/mir/pretty.rs +++ b/compiler/rustc_middle/src/mir/pretty.rs @@ -1075,7 +1075,7 @@ impl<'tcx> Debug for Rvalue<'tcx> { Some(CtorKind::Fn) => fmt_tuple(fmt, &name), None => { let mut struct_fmt = fmt.debug_struct(&name); - for (field, place) in iter::zip(&variant_def.fields, places) { + for (field, place) in iter::zip(variant_def.fields(), places) { struct_fmt.field(field.name.as_str(), place); } struct_fmt.finish() @@ -1831,7 +1831,7 @@ fn pretty_print_const_value_tcx<'tcx>( None => { fmt.write_str(" {{ ")?; let mut first = true; - for (field_def, (ct, ty)) in iter::zip(&variant_def.fields, fields) + for (field_def, (ct, ty)) in iter::zip(variant_def.fields(), fields) { if !first { fmt.write_str(", ")?; diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs index 412cfc1fc7a66..73e1f895ecd58 100644 --- a/compiler/rustc_middle/src/mir/tcx.rs +++ b/compiler/rustc_middle/src/mir/tcx.rs @@ -42,7 +42,7 @@ impl<'tcx> PlaceTy<'tcx> { adt_def.variant(variant_index) } }; - let field_def = &variant_def.fields[f]; + let field_def = &variant_def.fields()[f]; field_def.ty(tcx, args) } ty::Tuple(tys) => tys[f.index()], diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index c97af68c29e5f..1d66190210e63 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -1147,13 +1147,13 @@ impl<'tcx> fmt::Display for Pat<'tcx> { if let PatKind::Wild = p.pattern.kind { continue; } - let name = variant.fields[p.field].name; + let name = variant.fields()[p.field].name; write!(f, "{}{}: {}", start_or_comma(), name, p.pattern)?; printed += 1; } let is_union = self.ty.ty_adt_def().is_some_and(|adt| adt.is_union()); - if printed < variant.fields.len() && (!is_union || printed == 0) { + if printed < variant.fields().len() && (!is_union || printed == 0) { write!(f, "{}..", start_or_comma())?; } @@ -1162,7 +1162,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> { } let num_fields = - variant_and_name.as_ref().map_or(subpatterns.len(), |(v, _)| v.fields.len()); + variant_and_name.as_ref().map_or(subpatterns.len(), |(v, _)| v.fields().len()); if num_fields != 0 || variant_and_name.is_none() { write!(f, "(")?; for i in 0..num_fields { diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 88ee32eae9529..103398fd32c85 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -429,7 +429,7 @@ impl<'tcx> AdtDef<'tcx> { /// by this ADT (nested unnamed fields are not expanded). #[inline] pub fn all_fields(self) -> impl Iterator + Clone { - self.variants().iter().flat_map(|v| v.fields.iter()) + self.variants().iter().flat_map(|v| v.fields().into_iter()) } /// Whether the ADT lacks fields. Note that this includes uninhabited enums, @@ -449,7 +449,7 @@ impl<'tcx> AdtDef<'tcx> { }) { return false; } - self.variants().iter().all(|v| v.fields.is_empty()) + self.variants().iter().all(|v| v.fields().is_empty()) } /// Return a `VariantDef` given a variant id. diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs index bdd9a6bab2bee..c7774b85db1cf 100644 --- a/compiler/rustc_middle/src/ty/closure.rs +++ b/compiler/rustc_middle/src/ty/closure.rs @@ -113,7 +113,7 @@ impl<'tcx> CapturedPlace<'tcx> { write!( &mut symbol, "__{}", - def.variant(variant).fields[idx].name.as_str(), + def.variant(variant).fields()[idx].name.as_str(), ) .unwrap(); } @@ -315,7 +315,7 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc curr_string = format!( "{}.{}", curr_string, - def.variant(variant).fields[idx].name.as_str() + def.variant(variant).fields()[idx].name.as_str() ); } ty::Tuple(_) => { diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index afdf2cbc72667..9f467c6e2ab90 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -87,7 +87,7 @@ impl<'tcx> VariantDef { } InhabitedPredicate::all( tcx, - self.fields.iter().map(|field| { + self.fields().iter().map(|field| { let pred = tcx.type_of(field.did).instantiate_identity().inhabited_predicate(tcx); if adt.is_enum() { return pred; diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index eb25aecd9cef1..37546c75a9975 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -427,7 +427,7 @@ impl<'tcx> SizeSkeleton<'tcx> { let zero_or_ptr_variant = |i| { let i = VariantIdx::from_usize(i); let fields = - def.variant(i).fields.iter().map(|field| { + def.variant(i).fields().into_iter().map(|field| { SizeSkeleton::compute(field.ty(tcx, args), tcx, param_env) }); let mut ptr = None; @@ -749,7 +749,7 @@ where let fields = match this.ty.kind() { ty::Adt(def, _) if def.variants().is_empty() => bug!("for_variant called on zero-variant enum {}", this.ty), - ty::Adt(def, _) => def.variant(variant_index).fields.len(), + ty::Adt(def, _) => def.variant(variant_index).fields().len(), _ => bug!("`ty_and_layout_for_variant` on unexpected type {}", this.ty), }; tcx.mk_layout(LayoutS { @@ -918,7 +918,7 @@ where ty::Adt(def, args) => { match this.variants { Variants::Single { index } => { - let field = &def.variant(index).fields[FieldIdx::from_usize(i)]; + let field = &def.variant(index).fields()[FieldIdx::from_usize(i)]; TyMaybeWithLayout::Ty(field.ty(tcx, args)) } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 4470db47474cb..20dea034a30b5 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -1168,6 +1168,10 @@ bitflags::bitflags! { } rustc_data_structures::external_bitflags_debug! { VariantFlags } +/// When a variant is recovered from a syntactic error, we don't have complete information about it. +/// Return an empty list of fields in this case. +const EMPTY_FIELDS: &IndexVec = &IndexVec::new(); + /// Definition of a variant -- a struct's fields or an enum variant. #[derive(Debug, HashStable, TyEncodable, TyDecodable)] pub struct VariantDef { @@ -1182,7 +1186,7 @@ pub struct VariantDef { /// Discriminant of this variant. pub discr: VariantDiscr, /// Fields of this variant. - pub fields: IndexVec, + fields: Result, ErrorGuaranteed>, /// Flags of the variant (e.g. is field list non-exhaustive)? flags: VariantFlags, } @@ -1212,7 +1216,7 @@ impl VariantDef { fields: IndexVec, adt_kind: AdtKind, parent_did: DefId, - recovered: bool, + recovered: Option, is_field_list_non_exhaustive: bool, has_unnamed_fields: bool, ) -> Self { @@ -1227,7 +1231,7 @@ impl VariantDef { flags |= VariantFlags::IS_FIELD_LIST_NON_EXHAUSTIVE; } - if recovered { + if recovered.is_some() { flags |= VariantFlags::IS_RECOVERED; } @@ -1235,6 +1239,7 @@ impl VariantDef { flags |= VariantFlags::HAS_UNNAMED_FIELDS; } + let fields = if let Some(guard) = recovered { Err(guard) } else { Ok(fields) }; VariantDef { def_id: variant_did.unwrap_or(parent_did), ctor, name, discr, fields, flags } } @@ -1261,6 +1266,14 @@ impl VariantDef { Ident::new(self.name, tcx.def_ident_span(self.def_id).unwrap()) } + pub fn fields(&self) -> &IndexVec { + if let Ok(fields) = &self.fields { fields } else { EMPTY_FIELDS } + } + + pub fn fields_checked(&self) -> Result<&IndexVec, ErrorGuaranteed> { + self.fields.as_ref().map_err(|e| *e) + } + #[inline] pub fn ctor_kind(&self) -> Option { self.ctor.map(|(kind, _)| kind) @@ -1276,15 +1289,15 @@ impl VariantDef { /// `panic!`s if there are no fields or multiple fields. #[inline] pub fn single_field(&self) -> &FieldDef { - assert!(self.fields.len() == 1); + assert!(self.fields().len() == 1); - &self.fields[FieldIdx::ZERO] + &self.fields()[FieldIdx::ZERO] } /// Returns the last field in this variant, if present. #[inline] pub fn tail_opt(&self) -> Option<&FieldDef> { - self.fields.raw.last() + self.fields().raw.last() } /// Returns the last field in this variant. @@ -1631,7 +1644,7 @@ impl<'tcx> TyCtxt<'tcx> { } pub fn find_field_index(self, ident: Ident, variant: &VariantDef) -> Option { - variant.fields.iter_enumerated().find_map(|(i, field)| { + variant.fields().iter_enumerated().find_map(|(i, field)| { self.hygienic_eq(ident, field.ident(self), variant.def_id).then_some(i) }) } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index df080b2887b89..7ed3c720f064d 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1879,7 +1879,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { None => { p!(" {{ "); let mut first = true; - for (field_def, field) in iter::zip(&variant_def.fields, fields) { + for (field_def, field) in iter::zip(variant_def.fields(), fields) { if !first { p!(", "); } diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index d2b444a066bcc..b4c2dbfdc2247 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1092,7 +1092,7 @@ impl<'tcx> Ty<'tcx> { Adt(def, args) => { assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type"); let variant = def.non_enum_variant(); - let f0_ty = variant.fields[FieldIdx::ZERO].ty(tcx, args); + let f0_ty = variant.fields()[FieldIdx::ZERO].ty(tcx, args); match f0_ty.kind() { // If the first field is an array, we assume it is the only field and its @@ -1106,7 +1106,7 @@ impl<'tcx> Ty<'tcx> { } // Otherwise, the fields of this Adt are the SIMD components (and we assume they // all have the same type). - _ => (variant.fields.len() as u64, f0_ty), + _ => (variant.fields().len() as u64, f0_ty), } } _ => bug!("`simd_size_and_type` called on invalid type"), @@ -1500,7 +1500,7 @@ impl<'tcx> Ty<'tcx> { ty::Adt(adt_def, args) if adt_def.is_enum() || adt_def.is_struct() => self .adt_async_destructor_ty( tcx, - adt_def.variants().iter().map(|v| v.fields.iter().map(|f| f.ty(tcx, args))), + adt_def.variants().iter().map(|v| v.fields().iter().map(|f| f.ty(tcx, args))), ), ty::Tuple(tys) => self.adt_async_destructor_ty(tcx, iter::once(tys)), ty::Closure(_, args) => { diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs index 942c69b5c0a75..bebb6ff3dd2de 100644 --- a/compiler/rustc_mir_build/src/build/expr/into.rs +++ b/compiler/rustc_mir_build/src/build/expr/into.rs @@ -342,7 +342,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }) .collect(); - let field_names = adt_def.variant(variant_index).fields.indices(); + let field_names = adt_def.variant(variant_index).fields().indices(); let fields = if let Some(FruInfo { base, field_types }) = base { let place_builder = unpack!(block = this.as_place_builder(block, *base)); diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 5745dc0969cce..80b3fc51e3532 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -290,7 +290,7 @@ impl<'tcx> ConstToPat<'tcx> { subpatterns: self.field_pats( fields.iter().copied().zip( adt_def.variants()[variant_index] - .fields + .fields() .iter() .map(|field| field.ty(self.tcx(), args)), ), @@ -307,7 +307,7 @@ impl<'tcx> ConstToPat<'tcx> { subpatterns: self.field_pats( cv.unwrap_branch().iter().copied().zip( def.non_enum_variant() - .fields + .fields() .iter() .map(|field| field.ty(self.tcx(), args)), ), diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index fd778ef78a3ee..f9ae1cdbeaa25 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -379,7 +379,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { span_bug!(pat.span, "tuple struct pattern not applied to an ADT {:?}", ty); }; let variant_def = adt_def.variant_of_res(res); - let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields.len(), ddpos); + let subpatterns = self.lower_tuple_subpats(pats, variant_def.fields().len(), ddpos); self.lower_variant_or_leaf(res, pat.hir_id, pat.span, ty, subpatterns) } diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs index e0da9600ae37f..5b1c7e9f088f0 100644 --- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs +++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs @@ -268,7 +268,7 @@ where args: GenericArgsRef<'tcx>, ) -> Vec<(Place<'tcx>, Option)> { variant - .fields + .fields() .iter() .enumerate() .map(|(i, f)| { @@ -422,9 +422,9 @@ where ) -> BasicBlock { // drop glue is sent straight to codegen // box cannot be directly dereferenced - let unique_ty = adt.non_enum_variant().fields[FieldIdx::ZERO].ty(self.tcx(), args); + let unique_ty = adt.non_enum_variant().fields()[FieldIdx::ZERO].ty(self.tcx(), args); let unique_variant = unique_ty.ty_adt_def().unwrap().non_enum_variant(); - let nonnull_ty = unique_variant.fields[FieldIdx::ZERO].ty(self.tcx(), args); + let nonnull_ty = unique_variant.fields()[FieldIdx::ZERO].ty(self.tcx(), args); let ptr_ty = Ty::new_imm_ptr(self.tcx(), args[0].expect_ty()); let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::ZERO, unique_ty); @@ -549,7 +549,7 @@ where let param_env = self.elaborator.param_env(); let have_field_with_drop_glue = variant - .fields + .fields() .iter() .any(|field| field.ty(tcx, args).needs_drop(tcx, param_env)); if have_field_with_drop_glue { diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs index 1582c2e8a9061..eca24b374d978 100644 --- a/compiler/rustc_mir_dataflow/src/value_analysis.rs +++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs @@ -1180,7 +1180,7 @@ pub fn iter_fields<'tcx>( } for (v_index, v_def) in def.variants().iter_enumerated() { let variant = if def.is_struct() { None } else { Some(v_index) }; - for (f_index, f_def) in v_def.fields.iter().enumerate() { + for (f_index, f_def) in v_def.fields().iter().enumerate() { let field_ty = f_def.ty(tcx, args); let field_ty = tcx .try_normalize_erasing_regions(param_env, field_ty) diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 16977a63c598e..02afbb09d36c6 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -40,7 +40,9 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b ty::Adt(adt, args) => { depth == 0 || adt.variants().iter().any(|v| { - v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, args), depth - 1, tcx)) + v.fields() + .iter() + .any(|f| may_contain_reference(f.ty(tcx, args), depth - 1, tcx)) }) } // Conservative fallback diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs index 8b965f4d18e45..859a33521149e 100644 --- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs +++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs @@ -678,7 +678,7 @@ fn try_write_constant<'tcx>( (FIRST_VARIANT, def.non_enum_variant(), place, dest.clone()) }; - for (i, field) in variant_def.fields.iter_enumerated() { + for (i, field) in variant_def.fields().iter_enumerated() { let ty = field.ty(*ecx.tcx, args); let Some(field) = map.apply(variant_place, TrackElem::Field(i)) else { throw_machine_stop_str!("missing field in ADT") diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs index d955b96d06af0..4d8b14db9436b 100644 --- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs +++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs @@ -91,14 +91,14 @@ pub struct ElaborateBoxDerefs; impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { if let Some(def_id) = tcx.lang_items().owned_box() { - let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did; + let unique_did = tcx.adt_def(def_id).non_enum_variant().fields()[FieldIdx::ZERO].did; let Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def() else { span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique") }; - let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::ZERO].did; + let nonnull_did = nonnull_def.non_enum_variant().fields()[FieldIdx::ZERO].did; let patch = MirPatch::new(body); diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs index 8209e5e27111c..010ed342364aa 100644 --- a/compiler/rustc_mir_transform/src/instsimplify.rs +++ b/compiler/rustc_mir_transform/src/instsimplify.rs @@ -217,7 +217,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> { && let Some(place) = operand.place() { let variant = adt_def.non_enum_variant(); - for (i, field) in variant.fields.iter_enumerated() { + for (i, field) in variant.fields().iter_enumerated() { let field_ty = field.ty(self.tcx, args); if field_ty == *cast_ty { let place = place diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs index 7d12bcf2fa153..19d17667b30c4 100644 --- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs +++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs @@ -125,7 +125,7 @@ fn is_needs_drop_and_init<'tcx>( }; variant - .fields + .fields() .iter() .enumerate() .map(|(f, field)| (FieldIdx::from_usize(f), field.ty(tcx, args), mpi)) @@ -149,7 +149,7 @@ fn variant_needs_drop<'tcx>( args: GenericArgsRef<'tcx>, variant: &VariantDef, ) -> bool { - variant.fields.iter().any(|field| { + variant.fields().iter().any(|field| { let f_ty = field.ty(tcx, args); f_ty.needs_drop(tcx, param_env) }) diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index 6835a39cf3624..720f0747b6f1c 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -949,7 +949,7 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> { Place::return_place(), Rvalue::Aggregate( Box::new(kind), - (0..variant.fields.len()) + (0..variant.fields().len()) .map(|idx| Operand::Move(Place::from(Local::new(idx + 1)))) .collect(), ), diff --git a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs index ea4f5fca59e67..d50afd90203e7 100644 --- a/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs +++ b/compiler/rustc_mir_transform/src/shim/async_destructor_ctor.rs @@ -147,7 +147,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { ty::Tuple(elem_tys) => self.build_chain(None, elem_tys.iter()), ty::Adt(adt_def, args) if adt_def.is_struct() => { - let field_tys = adt_def.non_enum_variant().fields.iter().map(|f| f.ty(tcx, args)); + let field_tys = adt_def.non_enum_variant().fields().iter().map(|f| f.ty(tcx, args)); self.build_chain(surface_drop_kind(), field_tys) } ty::Closure(_, args) => self.build_chain(None, args.as_closure().upvar_tys().iter()), @@ -208,7 +208,7 @@ impl<'tcx> AsyncDestructorCtorShimBuilder<'tcx> { let variant = adt_def.variant(variant_idx); let mut chain = None; - for (field_idx, field) in variant.fields.iter_enumerated() { + for (field_idx, field) in variant.fields().iter_enumerated() { let field_ty = field.ty(tcx, args); self.put_variant_field(variant.name, variant_idx, field_idx, field_ty); let defer = self.combine_defer(field_ty); diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index c2108795372f6..e775b055ea50c 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -78,7 +78,7 @@ fn escaping_locals<'tcx>( } // We already excluded unions and enums, so this ADT must have one variant let variant = def.variant(FIRST_VARIANT); - if variant.fields.len() > 1 { + if variant.fields().len() > 1 { // If this has more than one field, it cannot be a wrapper that only provides a // niche, so we do not want to automatically exclude it. return false; diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index ab5c25c493773..fed09b71cbfdb 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -705,7 +705,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } let var = parent_ty.variant_index.unwrap_or(FIRST_VARIANT); - let Some(field) = adt_def.variant(var).fields.get(f) else { + let Some(field) = adt_def.variant(var).fields().get(f) else { fail_out_of_bounds(self, location); return; }; @@ -898,7 +898,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { assert_eq!(idx, FIRST_VARIANT); let dest_ty = self.tcx.normalize_erasing_regions( self.param_env, - adt_def.non_enum_variant().fields[field].ty(self.tcx, args), + adt_def.non_enum_variant().fields()[field].ty(self.tcx, args), ); if fields.len() == 1 { let src_ty = fields.raw[0].ty(self.body, self.tcx); @@ -913,10 +913,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { let adt_def = self.tcx.adt_def(def_id); assert!(!adt_def.is_union()); let variant = &adt_def.variants()[idx]; - if variant.fields.len() != fields.len() { + if variant.fields().len() != fields.len() { self.fail(location, "adt has the wrong number of initialized fields"); } - for (src, dest) in std::iter::zip(fields, &variant.fields) { + for (src, dest) in std::iter::zip(fields.iter(), variant.fields()) { let dest_ty = self .tcx .normalize_erasing_regions(self.param_env, dest.ty(self.tcx, args)); @@ -1327,7 +1327,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { current_ty = self.tcx.normalize_erasing_regions(self.param_env, f_ty); } ty::Adt(adt_def, args) => { - let Some(field) = adt_def.variant(variant).fields.get(field) else { + let Some(field) = adt_def.variant(variant).fields().get(field) else { fail_out_of_bounds(self, location, field, current_ty); return; }; diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index bfd505c06726d..634e79d4223bb 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1055,8 +1055,8 @@ fn find_vtable_types_for_unsizing<'tcx>( } }; - let source_fields = &source_adt_def.non_enum_variant().fields; - let target_fields = &target_adt_def.non_enum_variant().fields; + let source_fields = &source_adt_def.non_enum_variant().fields(); + let target_fields = &target_adt_def.non_enum_variant().fields(); assert!( coerce_index.index() < source_fields.len() diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 55514883cb1f8..a5e204a7e5e76 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -200,7 +200,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { match self.typeck_results().expr_ty_adjusted(lhs).kind() { ty::Adt(def, _) => { let index = self.typeck_results().field_index(hir_id); - self.insert_def_id(def.non_enum_variant().fields[index].did); + self.insert_def_id(def.non_enum_variant().fields()[index].did); } ty::Tuple(..) => {} ty::Error(_) => {} @@ -288,7 +288,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { continue; } let index = self.typeck_results().field_index(pat.hir_id); - self.insert_def_id(variant.fields[index].did); + self.insert_def_id(variant.fields()[index].did); } } @@ -311,13 +311,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { }; let dotdot = dotdot.as_opt_usize().unwrap_or(pats.len()); let first_n = pats.iter().enumerate().take(dotdot); - let missing = variant.fields.len() - pats.len(); + let missing = variant.fields().len() - pats.len(); let last_n = pats.iter().enumerate().skip(dotdot).map(|(idx, pat)| (idx + missing, pat)); for (idx, pat) in first_n.chain(last_n) { if let PatKind::Wild = pat.kind { continue; } - self.insert_def_id(variant.fields[FieldIdx::from_usize(idx)].did); + self.insert_def_id(variant.fields()[FieldIdx::from_usize(idx)].did); } } @@ -334,7 +334,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { for &(variant, field) in indices { match current_ty.kind() { ty::Adt(def, args) => { - let field = &def.variant(variant).fields[field]; + let field = &def.variant(variant).fields()[field]; self.insert_def_id(field.did); let field_ty = field.ty(self.tcx, args); @@ -537,10 +537,10 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { } fn mark_as_used_if_union(&mut self, adt: ty::AdtDef<'tcx>, fields: &[hir::ExprField<'_>]) { - if adt.is_union() && adt.non_enum_variant().fields.len() > 1 && adt.did().is_local() { + if adt.is_union() && adt.non_enum_variant().fields().len() > 1 && adt.did().is_local() { for field in fields { let index = self.typeck_results().field_index(field.hir_id); - self.insert_def_id(adt.non_enum_variant().fields[index].did); + self.insert_def_id(adt.non_enum_variant().fields()[index].did); } } } @@ -1291,13 +1291,13 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) { continue; } - let is_positional = variant.fields.raw.first().map_or(false, |field| { + let is_positional = variant.fields().raw.first().map_or(false, |field| { field.name.as_str().starts_with(|c: char| c.is_ascii_digit()) }); let report_on = if is_positional { ReportOn::TupleField } else { ReportOn::NamedField }; let dead_fields = variant - .fields + .fields() .iter() .filter_map(|field| { let def_id = field.did.expect_local(); diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs index d4dd4dd858c28..2daa23b45ce12 100644 --- a/compiler/rustc_pattern_analysis/src/rustc.rs +++ b/compiler/rustc_pattern_analysis/src/rustc.rs @@ -163,7 +163,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { ) -> impl Iterator)> + Captures<'p> + Captures<'_> { let ty::Adt(_, args) = ty.kind() else { bug!() }; - variant.fields.iter().map(move |field| { + variant.fields().iter().map(move |field| { let ty = field.ty(self.tcx, args); // `field.ty()` doesn't normalize after instantiating. let ty = self.tcx.normalize_erasing_regions(self.param_env, ty); @@ -269,7 +269,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { 1 } else { let variant_idx = RustcPatCtxt::variant_index_for_adt(&ctor, *adt); - adt.variant(variant_idx).fields.len() + adt.variant(variant_idx).fields().len() } } _ => bug!("Unexpected type for constructor `{ctor:?}`: {ty:?}"), @@ -512,7 +512,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> { }; let variant = &adt.variant(RustcPatCtxt::variant_index_for_adt(&ctor, *adt)); - arity = variant.fields.len(); + arity = variant.fields().len(); fields = subpatterns .iter() .map(|ipat| self.lower_pat(&ipat.pattern).at_index(ipat.field.index())) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index d37056269385d..0def1b615aef3 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -992,7 +992,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { // If the expression uses FRU we need to make sure all the unmentioned fields // are checked for privacy (RFC 736). Rather than computing the set of // unmentioned fields, just check them all. - for (vf_index, variant_field) in variant.fields.iter_enumerated() { + for (vf_index, variant_field) in variant.fields().iter_enumerated() { let field = fields .iter() .find(|f| self.typeck_results().field_index(f.hir_id) == vf_index); @@ -1006,7 +1006,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { for field in fields { let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span); let index = self.typeck_results().field_index(field.hir_id); - self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false); + self.check_field(hir_id, use_ctxt, span, adt, &variant.fields()[index], false); } } } @@ -1022,7 +1022,7 @@ impl<'tcx> Visitor<'tcx> for NamePrivacyVisitor<'tcx> { for field in fields { let (hir_id, use_ctxt, span) = (field.hir_id, field.ident.span, field.span); let index = self.typeck_results().field_index(field.hir_id); - self.check_field(hir_id, use_ctxt, span, adt, &variant.fields[index], false); + self.check_field(hir_id, use_ctxt, span, adt, &variant.fields()[index], false); } } diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs index f0f2d1fefd2f3..1d6a75b8c0edb 100644 --- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs +++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs @@ -135,7 +135,7 @@ impl<'tcx> TypeFolder> for TransformTy<'tcx> { } let variant = adt_def.non_enum_variant(); let param_env = self.tcx.param_env(variant.def_id); - let field = variant.fields.iter().find(|field| { + let field = variant.fields().iter().find(|field| { let ty = self.tcx.type_of(field.did).instantiate_identity(); let is_zst = self .tcx diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index b0ced8e920fe5..d6d05ece005b4 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -389,7 +389,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn variant_fields(&self, def: VariantDef) -> Vec { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; - def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect() + def.internal(&mut *tables, tcx).fields().iter().map(|f| f.stable(&mut *tables)).collect() } fn eval_target_usize(&self, cnst: &MirConst) -> Result { diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 5f8029af02044..4fbf8994d0fe6 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -674,7 +674,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> { } None => { self.push("S"); - for (field_def, field) in iter::zip(&variant_def.fields, fields) { + for (field_def, field) in iter::zip(variant_def.fields(), fields) { // HACK(eddyb) this mimics `path_append`, // instead of simply using `field_def.ident`, // just to be able to handle disambiguators. diff --git a/compiler/rustc_trait_selection/src/traits/misc.rs b/compiler/rustc_trait_selection/src/traits/misc.rs index baec2268629dc..657edb4cb11e5 100644 --- a/compiler/rustc_trait_selection/src/traits/misc.rs +++ b/compiler/rustc_trait_selection/src/traits/misc.rs @@ -134,7 +134,7 @@ pub fn all_fields_implement_trait<'tcx>( let mut infringing = Vec::new(); for variant in adt.variants() { - for field in &variant.fields { + for field in variant.fields() { // Do this per-field to get better error messages. let infcx = tcx.infer_ctxt().build(); let ocx = traits::ObligationCtxt::new_with_diagnostics(&infcx); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index cc082ad98aa99..0721ad91138ed 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2304,9 +2304,15 @@ impl<'tcx> SelectionContext<'_, 'tcx> { // if all of its fields are `Copy` and `Clone` ty::Adt(adt, args) if adt.is_anonymous() => { // (*) binder moved here - Where(obligation.predicate.rebind( - adt.non_enum_variant().fields.iter().map(|f| f.ty(self.tcx(), args)).collect(), - )) + Where( + obligation.predicate.rebind( + adt.non_enum_variant() + .fields() + .iter() + .map(|f| f.ty(self.tcx(), args)) + .collect(), + ), + ) } ty::Adt(..) | ty::Alias(..) | ty::Param(..) | ty::Placeholder(..) => { diff --git a/compiler/rustc_transmute/src/layout/tree.rs b/compiler/rustc_transmute/src/layout/tree.rs index 865f9487213f8..2c3ed656a191e 100644 --- a/compiler/rustc_transmute/src/layout/tree.rs +++ b/compiler/rustc_transmute/src/layout/tree.rs @@ -480,7 +480,7 @@ pub(crate) mod rustc { return Err(Err::NotYetSupported); }; - let fields = &def.non_enum_variant().fields; + let fields = &def.non_enum_variant().fields(); let fields = fields.iter_enumerated().try_fold( Self::uninhabited(), |fields, (idx, ref field_def)| { diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs index 2b052412e6b61..64b1540bdf800 100644 --- a/compiler/rustc_transmute/src/lib.rs +++ b/compiler/rustc_transmute/src/lib.rs @@ -170,7 +170,7 @@ mod rustc { let get_field = |name| { let (field_idx, _) = variant - .fields + .fields() .iter() .enumerate() .find(|(_, field_def)| name == field_def.name) diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 58f812fc7cfa1..64385820cf797 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -51,10 +51,10 @@ fn destructure_const<'tcx>( } else { (FIRST_VARIANT, branches) }; - let fields = &def.variant(variant_idx).fields; + let fields = &def.variant(variant_idx).fields(); let mut field_consts = Vec::with_capacity(fields.len()); - for (field, field_valtree) in iter::zip(fields, branches) { + for (field, field_valtree) in iter::zip(fields.iter(), branches) { let field_ty = field.ty(tcx, args); let field_const = ty::Const::new_value(tcx, *field_valtree, field_ty); field_consts.push(field_const); diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 6045abc50a9da..aa82690787009 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -397,7 +397,7 @@ fn layout_of_uncached<'tcx>( return Err(error(cx, LayoutError::Unknown(ty))); } - let fields = &def.non_enum_variant().fields; + let fields = &def.non_enum_variant().fields(); // Supported SIMD vectors are homogeneous ADTs with at least one field: // @@ -418,7 +418,7 @@ fn layout_of_uncached<'tcx>( // Heterogeneous SIMD vectors are not supported: // (should be caught by typeck) - for fi in fields { + for fi in fields.iter() { if fi.ty(tcx, args) != f0_ty { tcx.dcx().delayed_bug( "#[repr(simd)] was applied to an ADT with heterogeneous field type", @@ -439,7 +439,7 @@ fn layout_of_uncached<'tcx>( // SIMD vectors with multiple array fields are not supported: // Can't be caught by typeck with a generic simd type. - if def.non_enum_variant().fields.len() != 1 { + if def.non_enum_variant().fields().len() != 1 { tcx.dcx().emit_fatal(MultipleArrayFieldsSimdType { ty }); } @@ -451,7 +451,7 @@ fn layout_of_uncached<'tcx>( (*e_ty, *count, true) } else { // First ADT field is not an array: - (f0_ty, def.non_enum_variant().fields.len() as _, false) + (f0_ty, def.non_enum_variant().fields().len() as _, false) }; // SIMD vectors of zero length are not supported. @@ -521,7 +521,7 @@ fn layout_of_uncached<'tcx>( .variants() .iter() .map(|v| { - v.fields + v.fields() .iter() .map(|field| Ok(cx.layout_of(field.ty(tcx, args))?.layout)) .try_collect::>() @@ -565,7 +565,7 @@ fn layout_of_uncached<'tcx>( if def.is_struct() { if let Some((_, fields_except_last)) = - def.non_enum_variant().fields.raw.split_last() + def.non_enum_variant().fields().raw.split_last() { for f in fields_except_last { err_if_unsized(f, "only the last field of a struct can be unsized")?; @@ -1098,7 +1098,7 @@ fn variant_info_for_adt<'tcx>( if !adt_def.variants().is_empty() && layout.fields != FieldsShape::Primitive { debug!("print-type-size `{:#?}` variant {}", layout, adt_def.variant(index).name); let variant_def = &adt_def.variant(index); - let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); + let fields: Vec<_> = variant_def.fields().iter().map(|f| f.name).collect(); (vec![build_variant_info(Some(variant_def.name), &fields, layout)], None) } else { (vec![], None) @@ -1115,7 +1115,7 @@ fn variant_info_for_adt<'tcx>( .variants() .iter_enumerated() .map(|(i, variant_def)| { - let fields: Vec<_> = variant_def.fields.iter().map(|f| f.name).collect(); + let fields: Vec<_> = variant_def.fields().iter().map(|f| f.name).collect(); build_variant_info(Some(variant_def.name), &fields, layout.for_variant(cx, i)) }) .collect(); diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs index 5e91320f89753..2b76d95b33c98 100644 --- a/compiler/rustc_ty_utils/src/opaque_types.rs +++ b/compiler/rustc_ty_utils/src/opaque_types.rs @@ -291,7 +291,7 @@ impl<'tcx> TypeVisitor> for OpaqueTypeCollector<'tcx> { return; } for variant in def.variants().iter() { - for field in variant.fields.iter() { + for field in variant.fields().iter() { // Don't use the `ty::Adt` args, we either // * found the opaque in the args // * will find the opaque in the uninstantiated fields diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs index 0ffb7f624965e..00c4ad8cac621 100644 --- a/compiler/rustc_ty_utils/src/representability.rs +++ b/compiler/rustc_ty_utils/src/representability.rs @@ -23,7 +23,7 @@ fn representability(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Representability { match tcx.def_kind(def_id) { DefKind::Struct | DefKind::Union | DefKind::Enum => { for variant in tcx.adt_def(def_id).variants() { - for field in variant.fields.iter() { + for field in variant.fields().iter() { rtry!(tcx.representability(field.did.expect_local())); } } @@ -88,7 +88,7 @@ fn params_in_repr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> BitSet { let generics = tcx.generics_of(def_id); let mut params_in_repr = BitSet::new_empty(generics.own_params.len()); for variant in adt_def.variants() { - for field in variant.fields.iter() { + for field in variant.fields().iter() { params_in_repr_ty( tcx, tcx.type_of(field.did).instantiate_identity(), diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 38950c97c9d58..c0a210db173e4 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -325,7 +325,7 @@ fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet, did: DefId) -> clean::Struct { clean::Struct { ctor_kind: variant.ctor_kind(), generics: clean_ty_generics(cx, cx.tcx.generics_of(did), predicates), - fields: variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(), + fields: variant.fields().iter().map(|x| clean_middle_field(x, cx)).collect(), } } @@ -351,7 +351,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { let variant = cx.tcx.adt_def(did).non_enum_variant(); let generics = clean_ty_generics(cx, cx.tcx.generics_of(did), predicates); - let fields = variant.fields.iter().map(|x| clean_middle_field(x, cx)).collect(); + let fields = variant.fields().iter().map(|x| clean_middle_field(x, cx)).collect(); clean::Union { generics, fields } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index aa596897fc42f..09b50c7853305 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2374,10 +2374,10 @@ pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocCont let kind = match variant.ctor_kind() { Some(CtorKind::Const) => VariantKind::CLike, Some(CtorKind::Fn) => VariantKind::Tuple( - variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), + variant.fields().iter().map(|field| clean_middle_field(field, cx)).collect(), ), None => VariantKind::Struct(VariantStruct { - fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), + fields: variant.fields().iter().map(|field| clean_middle_field(field, cx)).collect(), }), }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 37f7e7ed38518..55495d6c5c70e 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -296,7 +296,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::Adt(def, _) if def.is_enum() => { if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name) && let Some(field) = - variant.fields.iter().find(|f| f.name == variant_field_name) + variant.fields().iter().find(|f| f.name == variant_field_name) { Ok((ty_res, field.did)) } else { diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index ff631909bcb58..61b6dcc36682f 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -179,7 +179,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { && adt_def.is_struct() && let Some(variant) = adt_def.variants().iter().next() { - let fields_def = &variant.fields; + let fields_def = &variant.fields(); // Push field type then visit each field expr. for field in *fields { diff --git a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs index 1075975f0a21e..23778b94210a6 100644 --- a/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs +++ b/src/tools/clippy/clippy_lints/src/inconsistent_struct_constructor.rs @@ -74,7 +74,7 @@ impl<'tcx> LateLintPass<'tcx> for InconsistentStructConstructor { && fields.iter().all(|f| f.is_shorthand) { let mut def_order_map = FxHashMap::default(); - for (idx, field) in variant.fields.iter().enumerate() { + for (idx, field) in variant.fields().iter().enumerate() { def_order_map.insert(field.name, idx); } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs index da8c918a62bb6..3e63825391dd1 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs @@ -288,7 +288,7 @@ impl<'a> NormalizedPat<'a> { front .iter() .map(|pat| Self::from_pat(cx, arena, pat)) - .chain(iter::repeat_with(|| Self::Wild).take(variant.fields.len() - pats.len())) + .chain(iter::repeat_with(|| Self::Wild).take(variant.fields().len() - pats.len())) .chain(back.iter().map(|pat| Self::from_pat(cx, arena, pat))), ); Self::Tuple(var_id, pats) diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs index 8d22ceb47f859..066015845db40 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_enum.rs @@ -128,7 +128,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>]) { }, variant.name, match variant.ctor_kind() { - Some(CtorKind::Fn) if variant.fields.len() == 1 => "(_)", + Some(CtorKind::Fn) if variant.fields().len() == 1 => "(_)", Some(CtorKind::Fn) => "(..)", Some(CtorKind::Const) => "", None => "{ .. }", diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index 74e6c57b52d46..7372277c1e5ac 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -95,7 +95,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { let mut non_send_fields = Vec::new(); for variant in adt_def.variants() { - for field in &variant.fields { + for field in &variant.fields() { if let Some(field_hir_id) = field .did .as_local() diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 8cf42832761f5..1fae605765f3b 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -131,11 +131,11 @@ impl UnnecessaryDefPath { let has_ctor = match cx.tcx.def_kind(def_id) { DefKind::Struct => { let variant = cx.tcx.adt_def(def_id).non_enum_variant(); - variant.ctor.is_some() && variant.fields.iter().all(|f| f.vis.is_public()) + variant.ctor.is_some() && variant.fields().iter().all(|f| f.vis.is_public()) }, DefKind::Variant => { let variant = cx.tcx.adt_def(cx.tcx.parent(def_id)).variant_with_id(def_id); - variant.ctor.is_some() && variant.fields.iter().all(|f| f.vis.is_public()) + variant.ctor.is_some() && variant.fields().iter().all(|f| f.vis.is_public()) }, _ => false, }; diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index de6ccfe476fb0..40f7fff61bfae 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -937,7 +937,7 @@ fn field_of_struct<'tcx>( && let Some(dc) = lcx.tcx.try_destructure_mir_constant_for_user_output(result, ty) && let Some(dc_variant) = dc.variant && let Some(variant) = adt_def.variants().get(dc_variant) - && let Some(field_idx) = variant.fields.iter().position(|el| el.name == field.name) + && let Some(field_idx) = variant.fields().iter().position(|el| el.name == field.name) && let Some(&(val, ty)) = dc.fields.get(field_idx) { Some(mir::Const::Val(val, ty)) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 184dab8367c16..42564a72dd456 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -81,7 +81,7 @@ impl Attrs { let krate = loc.parent.lookup(db).container.krate; let item_tree = loc.id.item_tree(db); let variant = &item_tree[loc.id.value]; - (variant.fields.clone(), item_tree, krate) + (variant.fields().clone(), item_tree, krate) } VariantId::StructId(it) => { let loc = it.lookup(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs index 0fe73418e51fc..115e646b66a92 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs @@ -343,7 +343,7 @@ impl EnumVariantData { container.local_id, &item_tree, &db.crate_graph()[krate].cfg_options, - &variant.fields, + &variant.fields(), Some(item_tree[loc.parent.lookup(db).id.value].visibility), ); diff --git a/src/tools/rust-analyzer/crates/hir/src/display.rs b/src/tools/rust-analyzer/crates/hir/src/display.rs index 79069ed66bf03..14473ef21ea4e 100644 --- a/src/tools/rust-analyzer/crates/hir/src/display.rs +++ b/src/tools/rust-analyzer/crates/hir/src/display.rs @@ -345,12 +345,12 @@ fn write_variants( match variant.kind(f.db) { StructKind::Tuple => { let fields_str = - if variant.fields(f.db).is_empty() { "()" } else { "( /* … */ )" }; + if variant.fields()(f.db).is_empty() { "()" } else { "( /* … */ )" }; f.write_str(fields_str)?; } StructKind::Record => { let fields_str = - if variant.fields(f.db).is_empty() { " {}" } else { " { /* … */ }" }; + if variant.fields()(f.db).is_empty() { " {}" } else { " { /* … */ }" }; f.write_str(fields_str)?; } StructKind::Unit => {} diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index c1fe8a8b316fe..4d6a20a759915 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -4106,7 +4106,7 @@ impl Type { adt_datum_bound .variants .into_iter() - .flat_map(|variant| variant.fields.into_iter()) + .flat_map(|variant| variant.fields().into_iter()) .any(|ty| go(db, krate, &ty)) || substitution .iter(Interner) diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs index bb687f5e73d27..25bf49c626aeb 100644 --- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs +++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs @@ -233,7 +233,7 @@ impl Expr { format!("{generics_str}({args})") } StructKind::Record => { - let fields = variant.fields(db); + let fields = variant.fields()(db); let args = params .iter() .zip(fields.iter()) diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs index 6091f06b96699..dfb454591780b 100644 --- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs +++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_from_impl_for_enum.rs @@ -90,7 +90,7 @@ fn existing_from_impl( let enum_type = enum_.ty(sema.db); - let wrapped_type = variant.fields(sema.db).first()?.ty(sema.db); + let wrapped_type = variant.fields()(sema.db).first()?.ty(sema.db); if enum_type.impls_trait(sema.db, from_trait, &[wrapped_type]) { Some(()) diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs index 942670be2a30f..e8625d19c9dd9 100644 --- a/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs +++ b/src/tools/rust-analyzer/crates/ide-completion/src/render/pattern.rs @@ -52,7 +52,7 @@ pub(crate) fn render_variant_pat( ) -> Option { let _p = tracing::info_span!("render_variant_pat").entered(); - let fields = variant.fields(ctx.db()); + let fields = variant.fields()(ctx.db()); let (visible_fields, fields_omitted) = visible_fields(ctx.completion, &fields, variant)?; let enum_ty = variant.parent_enum(ctx.db()).ty(ctx.db()); diff --git a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs index 89c725a6c4769..954a55016ed5d 100644 --- a/src/tools/rust-analyzer/crates/ide/src/signature_help.rs +++ b/src/tools/rust-analyzer/crates/ide/src/signature_help.rs @@ -452,7 +452,7 @@ fn signature_help_for_tuple_struct_pat( en.name(db).display(db), variant.name(db).display(db) ); - variant.fields(db) + variant.fields()(db) } else { let adt = match path_res { PathResolution::SelfType(imp) => imp.self_ty(db).as_adt()?, @@ -563,7 +563,7 @@ fn signature_help_for_record_( let db = sema.db; let path_res = sema.resolve_path(path)?; if let PathResolution::Def(ModuleDef::Variant(variant)) = path_res { - fields = variant.fields(db); + fields = variant.fields()(db); let en = variant.parent_enum(db); res.doc = en.docs(db); diff --git a/src/tools/rustfmt/config_proc_macro/src/item_enum.rs b/src/tools/rustfmt/config_proc_macro/src/item_enum.rs index 731a7ea06077b..f17a121ba32ca 100644 --- a/src/tools/rustfmt/config_proc_macro/src/item_enum.rs +++ b/src/tools/rustfmt/config_proc_macro/src/item_enum.rs @@ -58,7 +58,7 @@ fn process_variant(variant: &syn::Variant) -> TokenStream { /// internal field data. fn fields_in_variant(variant: &syn::Variant) -> TokenStream { // With thanks to https://stackoverflow.com/a/65182902 - match &variant.fields { + match &variant.fields() { syn::Fields::Unnamed(_) => quote_spanned! { variant.span() => (..) }, syn::Fields::Unit => quote_spanned! { variant.span() => }, syn::Fields::Named(_) => quote_spanned! { variant.span() => {..} }, diff --git a/tests/ui/pattern/struct-parser-recovery-issue-126344.rs b/tests/ui/pattern/struct-parser-recovery-issue-126344.rs new file mode 100644 index 0000000000000..1e3ce3e025e87 --- /dev/null +++ b/tests/ui/pattern/struct-parser-recovery-issue-126344.rs @@ -0,0 +1,42 @@ +struct Wrong { + x: i32; //~ ERROR struct fields are separated by `,` + y: i32, + z: i32, + h: i32, +} + +fn oops(w: &Wrong) { + w.x; +} + +fn foo(w: &Wrong) { + w.y; +} + +fn haha(w: &Wrong) { + w.z; +} + +struct WrongWithType { + x: 1, //~ ERROR expected type, found `1` + y: i32, + z: i32, + h: i32, +} + +fn oops_type(w: &WrongWithType) { + w.x; +} + +fn foo_type(w: &WrongWithType) { + w.y; +} + +fn haha_type(w: &WrongWithType) { + w.z; +} + +fn main() { + let v = Wrong { x: 1, y: 2, z: 3, h: 4 }; + let x = WrongWithType { x: 1, y: 2, z: 3, h: 4 }; +} diff --git a/tests/ui/pattern/struct-parser-recovery-issue-126344.stderr b/tests/ui/pattern/struct-parser-recovery-issue-126344.stderr new file mode 100644 index 0000000000000..ef7f9c566db37 --- /dev/null +++ b/tests/ui/pattern/struct-parser-recovery-issue-126344.stderr @@ -0,0 +1,18 @@ +error: struct fields are separated by `,` + --> $DIR/struct-parser-recovery-issue-126344.rs:2:11 + | +LL | struct Wrong { + | ----- while parsing this struct +LL | x: i32; + | ^ help: replace `;` with `,` + +error: expected type, found `1` + --> $DIR/struct-parser-recovery-issue-126344.rs:21:8 + | +LL | struct WrongWithType { + | ------------- while parsing this struct +LL | x: 1, + | ^ expected type + +error: aborting due to 2 previous errors + diff --git a/tests/ui/thir-print/thir-tree-match.stdout b/tests/ui/thir-print/thir-tree-match.stdout index 31c46716a006d..e8b37caae0935 100644 --- a/tests/ui/thir-print/thir-tree-match.stdout +++ b/tests/ui/thir-print/thir-tree-match.stdout @@ -92,7 +92,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: Ok([FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }]), flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: Ok([]), flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -106,7 +106,7 @@ body: adt_def: AdtDef { did: DefId(0:3 ~ thir_tree_match[fcf8]::Bar) - variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: [], flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: [], flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:4 ~ thir_tree_match[fcf8]::Bar::First), ctor: Some((Const, DefId(0:5 ~ thir_tree_match[fcf8]::Bar::First::{constructor#0}))), name: "First", discr: Relative(0), fields: Ok([]), flags: }, VariantDef { def_id: DefId(0:6 ~ thir_tree_match[fcf8]::Bar::Second), ctor: Some((Const, DefId(0:7 ~ thir_tree_match[fcf8]::Bar::Second::{constructor#0}))), name: "Second", discr: Relative(1), fields: Ok([]), flags: }, VariantDef { def_id: DefId(0:8 ~ thir_tree_match[fcf8]::Bar::Third), ctor: Some((Const, DefId(0:9 ~ thir_tree_match[fcf8]::Bar::Third::{constructor#0}))), name: "Third", discr: Relative(2), fields: Ok([]), flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 10333377570083945360 } args: [] @@ -154,7 +154,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: Ok([FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }]), flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: Ok([]), flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] @@ -206,7 +206,7 @@ body: adt_def: AdtDef { did: DefId(0:10 ~ thir_tree_match[fcf8]::Foo) - variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: [FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }], flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: [], flags: }] + variants: [VariantDef { def_id: DefId(0:11 ~ thir_tree_match[fcf8]::Foo::FooOne), ctor: Some((Fn, DefId(0:12 ~ thir_tree_match[fcf8]::Foo::FooOne::{constructor#0}))), name: "FooOne", discr: Relative(0), fields: Ok([FieldDef { did: DefId(0:13 ~ thir_tree_match[fcf8]::Foo::FooOne::0), name: "0", vis: Restricted(DefId(0:0 ~ thir_tree_match[fcf8])) }]), flags: }, VariantDef { def_id: DefId(0:14 ~ thir_tree_match[fcf8]::Foo::FooTwo), ctor: Some((Const, DefId(0:15 ~ thir_tree_match[fcf8]::Foo::FooTwo::{constructor#0}))), name: "FooTwo", discr: Relative(1), fields: Ok([]), flags: }] flags: IS_ENUM repr: ReprOptions { int: None, align: None, pack: None, flags: , field_shuffle_seed: 3477539199540094892 } args: [] diff --git a/tests/ui/typeck/struct-index-err-ice-issue-126744.rs b/tests/ui/typeck/struct-index-err-ice-issue-126744.rs new file mode 100644 index 0000000000000..00edc4d8e41e7 --- /dev/null +++ b/tests/ui/typeck/struct-index-err-ice-issue-126744.rs @@ -0,0 +1,7 @@ +struct X {,} //~ ERROR expected identifier, found `,` + +fn main() { + || { + if let X { x: 1,} = (X {}) {} + }; +} diff --git a/tests/ui/typeck/struct-index-err-ice-issue-126744.stderr b/tests/ui/typeck/struct-index-err-ice-issue-126744.stderr new file mode 100644 index 0000000000000..84a3af9ab0057 --- /dev/null +++ b/tests/ui/typeck/struct-index-err-ice-issue-126744.stderr @@ -0,0 +1,10 @@ +error: expected identifier, found `,` + --> $DIR/struct-index-err-ice-issue-126744.rs:1:11 + | +LL | struct X {,} + | - ^ expected identifier + | | + | while parsing this struct + +error: aborting due to 1 previous error +