Skip to content

Commit 6802e1d

Browse files
committed
Use AdtDef in wfcheck.
1 parent b03502b commit 6802e1d

File tree

1 file changed

+28
-79
lines changed

1 file changed

+28
-79
lines changed

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 28 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -218,19 +218,16 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
218218
hir::ItemKind::Const(ty, ..) => {
219219
check_item_type(tcx, def_id, ty.span, false);
220220
}
221-
hir::ItemKind::Struct(ref struct_def, ref ast_generics) => {
222-
check_type_defn(tcx, item, false, |wfcx| vec![wfcx.non_enum_variant(struct_def)]);
223-
221+
hir::ItemKind::Struct(_, ref ast_generics) => {
222+
check_type_defn(tcx, item, false);
224223
check_variances_for_type_defn(tcx, item, ast_generics);
225224
}
226-
hir::ItemKind::Union(ref struct_def, ref ast_generics) => {
227-
check_type_defn(tcx, item, true, |wfcx| vec![wfcx.non_enum_variant(struct_def)]);
228-
225+
hir::ItemKind::Union(_, ref ast_generics) => {
226+
check_type_defn(tcx, item, true);
229227
check_variances_for_type_defn(tcx, item, ast_generics);
230228
}
231-
hir::ItemKind::Enum(ref enum_def, ref ast_generics) => {
232-
check_type_defn(tcx, item, true, |wfcx| wfcx.enum_variants(enum_def));
233-
229+
hir::ItemKind::Enum(_, ref ast_generics) => {
230+
check_type_defn(tcx, item, true);
234231
check_variances_for_type_defn(tcx, item, ast_generics);
235232
}
236233
hir::ItemKind::Trait(..) => {
@@ -1037,35 +1034,33 @@ fn item_adt_kind(kind: &ItemKind<'_>) -> Option<AdtKind> {
10371034
}
10381035

10391036
/// In a type definition, we check that to ensure that the types of the fields are well-formed.
1040-
fn check_type_defn<'tcx, F>(
1041-
tcx: TyCtxt<'tcx>,
1042-
item: &hir::Item<'tcx>,
1043-
all_sized: bool,
1044-
mut lookup_fields: F,
1045-
) where
1046-
F: FnMut(&WfCheckingCtxt<'_, 'tcx>) -> Vec<AdtVariant<'tcx>>,
1047-
{
1037+
fn check_type_defn<'tcx>(tcx: TyCtxt<'tcx>, item: &hir::Item<'tcx>, all_sized: bool) {
10481038
let _ = tcx.representability(item.owner_id.def_id);
1039+
let adt_def = tcx.adt_def(item.owner_id);
10491040

10501041
enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
1051-
let variants = lookup_fields(wfcx);
1052-
let packed = tcx.adt_def(item.owner_id).repr().packed();
1042+
let variants = adt_def.variants();
1043+
let packed = adt_def.repr().packed();
10531044

1054-
for variant in &variants {
1045+
for variant in variants.iter() {
10551046
// All field types must be well-formed.
10561047
for field in &variant.fields {
1048+
let field_id = field.did.expect_local();
1049+
let hir::Node::Field(hir::FieldDef { ty: hir_ty, .. }) = tcx.hir().get_by_def_id(field_id)
1050+
else { bug!() };
1051+
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did));
10571052
wfcx.register_wf_obligation(
1058-
field.span,
1059-
Some(WellFormedLoc::Ty(field.def_id)),
1060-
field.ty.into(),
1053+
hir_ty.span,
1054+
Some(WellFormedLoc::Ty(field_id)),
1055+
ty.into(),
10611056
)
10621057
}
10631058

10641059
// For DST, or when drop needs to copy things around, all
10651060
// intermediate types must be sized.
10661061
let needs_drop_copy = || {
10671062
packed && {
1068-
let ty = variant.fields.last().unwrap().ty;
1063+
let ty = tcx.type_of(variant.fields.last().unwrap().did);
10691064
let ty = tcx.erase_regions(ty);
10701065
if ty.needs_infer() {
10711066
tcx.sess
@@ -1084,27 +1079,31 @@ fn check_type_defn<'tcx, F>(
10841079
variant.fields[..variant.fields.len() - unsized_len].iter().enumerate()
10851080
{
10861081
let last = idx == variant.fields.len() - 1;
1082+
let field_id = field.did.expect_local();
1083+
let hir::Node::Field(hir::FieldDef { ty: hir_ty, .. }) = tcx.hir().get_by_def_id(field_id)
1084+
else { bug!() };
1085+
let ty = wfcx.normalize(hir_ty.span, None, tcx.type_of(field.did));
10871086
wfcx.register_bound(
10881087
traits::ObligationCause::new(
1089-
field.span,
1088+
hir_ty.span,
10901089
wfcx.body_id,
10911090
traits::FieldSized {
10921091
adt_kind: match item_adt_kind(&item.kind) {
10931092
Some(i) => i,
10941093
None => bug!(),
10951094
},
1096-
span: field.span,
1095+
span: hir_ty.span,
10971096
last,
10981097
},
10991098
),
11001099
wfcx.param_env,
1101-
field.ty,
1100+
ty,
11021101
tcx.require_lang_item(LangItem::Sized, None),
11031102
);
11041103
}
11051104

11061105
// Explicit `enum` discriminant values must const-evaluate successfully.
1107-
if let Some(discr_def_id) = variant.explicit_discr {
1106+
if let ty::VariantDiscr::Explicit(discr_def_id) = variant.discr {
11081107
let cause = traits::ObligationCause::new(
11091108
tcx.def_span(discr_def_id),
11101109
wfcx.body_id,
@@ -1114,7 +1113,7 @@ fn check_type_defn<'tcx, F>(
11141113
cause,
11151114
wfcx.param_env,
11161115
ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(
1117-
ty::Const::from_anon_const(tcx, discr_def_id),
1116+
ty::Const::from_anon_const(tcx, discr_def_id.expect_local()),
11181117
))
11191118
.to_predicate(tcx),
11201119
));
@@ -1925,56 +1924,6 @@ fn check_mod_type_wf(tcx: TyCtxt<'_>, module: LocalDefId) {
19251924
items.par_foreign_items(|item| tcx.ensure().check_well_formed(item.owner_id));
19261925
}
19271926

1928-
///////////////////////////////////////////////////////////////////////////
1929-
// ADT
1930-
1931-
// FIXME(eddyb) replace this with getting fields/discriminants through `ty::AdtDef`.
1932-
struct AdtVariant<'tcx> {
1933-
/// Types of fields in the variant, that must be well-formed.
1934-
fields: Vec<AdtField<'tcx>>,
1935-
1936-
/// Explicit discriminant of this variant (e.g. `A = 123`),
1937-
/// that must evaluate to a constant value.
1938-
explicit_discr: Option<LocalDefId>,
1939-
}
1940-
1941-
struct AdtField<'tcx> {
1942-
ty: Ty<'tcx>,
1943-
def_id: LocalDefId,
1944-
span: Span,
1945-
}
1946-
1947-
impl<'a, 'tcx> WfCheckingCtxt<'a, 'tcx> {
1948-
// FIXME(eddyb) replace this with getting fields through `ty::AdtDef`.
1949-
fn non_enum_variant(&self, struct_def: &hir::VariantData<'_>) -> AdtVariant<'tcx> {
1950-
let fields = struct_def
1951-
.fields()
1952-
.iter()
1953-
.map(|field| {
1954-
let def_id = self.tcx().hir().local_def_id(field.hir_id);
1955-
let field_ty = self.tcx().type_of(def_id);
1956-
let field_ty = self.normalize(field.ty.span, None, field_ty);
1957-
debug!("non_enum_variant: type of field {:?} is {:?}", field, field_ty);
1958-
AdtField { ty: field_ty, span: field.ty.span, def_id }
1959-
})
1960-
.collect();
1961-
AdtVariant { fields, explicit_discr: None }
1962-
}
1963-
1964-
fn enum_variants(&self, enum_def: &hir::EnumDef<'_>) -> Vec<AdtVariant<'tcx>> {
1965-
enum_def
1966-
.variants
1967-
.iter()
1968-
.map(|variant| AdtVariant {
1969-
fields: self.non_enum_variant(&variant.data).fields,
1970-
explicit_discr: variant
1971-
.disr_expr
1972-
.map(|explicit_discr| self.tcx().hir().local_def_id(explicit_discr.hir_id)),
1973-
})
1974-
.collect()
1975-
}
1976-
}
1977-
19781927
fn error_392(
19791928
tcx: TyCtxt<'_>,
19801929
span: Span,

0 commit comments

Comments
 (0)