diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2022-10-30 07:57:23 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2022-10-31 11:21:46 +0000 |
| commit | 6802e1da380ed6f5cdad0b6b312ad4cfd7f94a3e (patch) | |
| tree | 5a0a5dcc00e52d242095dd5db686f0e2d7070d69 /compiler | |
| parent | b03502b35d111bef0399a66ab3cc765f0802e8ba (diff) | |
| download | rust-6802e1da380ed6f5cdad0b6b312ad4cfd7f94a3e.tar.gz rust-6802e1da380ed6f5cdad0b6b312ad4cfd7f94a3e.zip | |
Use AdtDef in wfcheck.
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_hir_analysis/src/check/wfcheck.rs | 107 |
1 files changed, 28 insertions, 79 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index a2357500465..99d0beacfa0 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -218,19 +218,16 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) { hir::ItemKind::Const(ty, ..) => { check_item_type(tcx, def_id, ty.span, false); } - hir::ItemKind::Struct(ref struct_def, ref ast_generics) => { - check_type_defn(tcx, item, false, |wfcx| vec![wfcx.non_enum_variant(struct_def)]); - + hir::ItemKind::Struct(_, ref ast_generics) => { + check_type_defn(tcx, item, false); check_variances_for_type_defn(tcx, item, ast_generics); } - hir::ItemKind::Union(ref struct_def, ref ast_generics) => { - check_type_defn(tcx, item, true, |wfcx| vec![wfcx.non_enum_variant(struct_def)]); - + hir::ItemKind::Union(_, ref ast_generics) => { + check_type_defn(tcx, item, true); check_variances_for_type_defn(tcx, item, ast_generics); } - hir::ItemKind::Enum(ref enum_def, ref ast_generics) => { - check_type_defn(tcx, item, true, |wfcx| wfcx.enum_variants(enum_def)); - + hir::ItemKind::Enum(_, ref ast_generics) => { + check_type_defn(tcx, item, true); check_variances_for_type_defn(tcx, item, ast_generics); } hir::ItemKind::Trait(..) => { @@ -1037,27 +1034,25 @@ fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> { } /// In a type definition, we check that to ensure that the types of the fields are well-formed. -fn check_type_defn<'tcx, F>( - tcx: TyCtxt<'tcx>, - item: &hir::Item<'tcx>, - all_sized: bool, - mut lookup_fields: F, -) where - F: FnMut(&WfCheckingCtxt<'_, 'tcx>) -> Vec<AdtVariant<'tcx>>, -{ +fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: bool) { let _ = tcx.representability(item.owner_id.def_id); + let adt_def = tcx.adt_def(item.owner_id); enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| { - let variants = lookup_fields(wfcx); - let packed = tcx.adt_def(item.owner_id).repr().packed(); + let variants = adt_def.variants(); + let packed = adt_def.repr().packed(); - for variant in &variants { + for variant in variants.iter() { // All field types must be well-formed. for field in &variant.fields { + let field_id = field.did.expect_local(); + let hir::Node::Field(hir::FieldDef { ty: hir_ty, .. }) = tcx.hir().get_by_def_id(field_id) + else { bug!() }; + let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did)); wfcx.register_wf_obligation( - field.span, - Some(WellFormedLoc::Ty(field.def_id)), - field.ty.into(), + hir_ty.span, + Some(WellFormedLoc::Ty(field_id)), + ty.into(), ) } @@ -1065,7 +1060,7 @@ fn check_type_defn<'tcx, F>( // intermediate types must be sized. let needs_drop_copy = || { packed && { - let ty = variant.fields.last().unwrap().ty; + let ty = tcx.type_of(variant.fields.last().unwrap().did); let ty = tcx.erase_regions(ty); if ty.needs_infer() { tcx.sess @@ -1084,27 +1079,31 @@ fn check_type_defn<'tcx, F>( variant.fields[..variant.fields.len() - unsized_len].iter().enumerate() { let last = idx == variant.fields.len() - 1; + let field_id = field.did.expect_local(); + let hir::Node::Field(hir::FieldDef { ty: hir_ty, .. }) = tcx.hir().get_by_def_id(field_id) + else { bug!() }; + let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did)); wfcx.register_bound( traits::ObligationCause::new( - field.span, + hir_ty.span, wfcx.body_id, traits::FieldSized { adt_kind: match item_adt_kind(&item.kind) { Some(i) => i, None => bug!(), }, - span: field.span, + span: hir_ty.span, last, }, ), wfcx.param_env, - field.ty, + ty, tcx.require_lang_item(LangItem::Sized, None), ); } // Explicit `enum` discriminant values must const-evaluate successfully. - if let Some(discr_def_id) = variant.explicit_discr { + if let ty::VariantDiscr::Explicit(discr_def_id) = variant.discr { let cause = traits::ObligationCause::new( tcx.def_span(discr_def_id), wfcx.body_id, @@ -1114,7 +1113,7 @@ fn check_type_defn<'tcx, F>( cause, wfcx.param_env, ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable( - ty::Const::from_anon_const(tcx, discr_def_id), + ty::Const::from_anon_const(tcx, discr_def_id.expect_local()), )) .to_predicate(tcx), )); @@ -1925,56 +1924,6 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) { items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id)); } -/////////////////////////////////////////////////////////////////////////// -// ADT - -// FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`. -struct AdtVariant<'tcx> { - /// Types of fields in the variant, that must be well-formed. - fields: Vec<AdtField<'tcx>>, - - /// Explicit discriminant of this variant (e.g. `A = 123`), - /// that must evaluate to a constant value. - explicit_discr: Option<LocalDefId>, -} - -struct AdtField<'tcx> { - ty: Ty<'tcx>, - def_id: LocalDefId, - span: Span, -} - -impl<'a, 'tcx> WfCheckingCtxt<'a, 'tcx> { - // FIXME(eddyb) replace this with getting fields through `ty::AdtDef`. - fn non_enum_variant(&self, struct_def: &hir::VariantData<'_>) -> AdtVariant<'tcx> { - let fields = struct_def - .fields() - .iter() - .map(|field| { - let def_id = self.tcx().hir().local_def_id(field.hir_id); - let field_ty = self.tcx().type_of(def_id); - let field_ty = self.normalize(field.ty.span, None, field_ty); - debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty); - AdtField { ty: field_ty, span: field.ty.span, def_id } - }) - .collect(); - AdtVariant { fields, explicit_discr: None } - } - - fn enum_variants(&self, enum_def: &hir::EnumDef<'_>) -> Vec<AdtVariant<'tcx>> { - enum_def - .variants - .iter() - .map(|variant| AdtVariant { - fields: self.non_enum_variant(&variant.data).fields, - explicit_discr: variant - .disr_expr - .map(|explicit_discr| self.tcx().hir().local_def_id(explicit_discr.hir_id)), - }) - .collect() - } -} - fn error_392( tcx: TyCtxt<'_>, span: Span, |
