Skip to content

Commit acf2d65

Browse files
committed
enforce discriminant to be the first field
1 parent 159401c commit acf2d65

File tree

1 file changed

+21
-25
lines changed

1 file changed

+21
-25
lines changed

lints/type_cosplay/src/lib.rs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -145,33 +145,29 @@ fn check_structs_have_discriminant(cx: &LateContext<'_>, types: &Vec<(DefId, Spa
145145
.for_each(|t| has_discriminant(cx, cx.tcx.adt_def(t.0), num_structs, t.1));
146146
}
147147

148-
/// Returns true if the `adt` has a field that is an enum and the number of variants of that enum is at least the number of deserialized struct types collected.
149-
fn has_discriminant(cx: &LateContext, adt: AdtDef, num_struct_types: usize, span: Span) {
150-
// TODO: why do we need to enforce that the first field is the discriminant?
148+
/// Checks if `adt` has a proper discriminant. We define a proper discriminant as being an enum with
149+
/// the number of variants at least the number of deserialized structs. Further the discriminant should
150+
/// be the first field in the adt.
151+
fn has_discriminant(cx: &LateContext, adt: &AdtDef, num_struct_types: usize, span: Span) {
151152
let variant = adt.variants().get(Idx::new(0)).unwrap();
152-
let has_discriminant = variant.fields.iter().any(|field| {
153-
let ty = cx.tcx.type_of(field.did);
154-
if_chain! {
155-
if let MiddleTyKind::Adt(adt_def, _) = ty.kind();
156-
if adt_def.is_enum();
157-
if adt_def.variants().len() >= num_struct_types;
158-
then {
159-
true
160-
} else {
161-
false
162-
}
153+
let first_field_def = &variant.fields[0];
154+
let ty = cx.tcx.type_of(first_field_def.did);
155+
if_chain! {
156+
if let MiddleTyKind::Adt(adt_def, _) = ty.kind();
157+
if adt_def.is_enum();
158+
if adt_def.variants().len() >= num_struct_types;
159+
then {
160+
// struct has a proper discriminant
161+
} else {
162+
span_lint_and_help(
163+
cx,
164+
TYPE_COSPLAY,
165+
span,
166+
"warning: type does not have a proper discriminant. It may be indistinguishable when deserialized.",
167+
None,
168+
"help: add an enum with at least as many variants as there are struct definitions"
169+
)
163170
}
164-
});
165-
166-
if !has_discriminant {
167-
span_lint_and_help(
168-
cx,
169-
TYPE_COSPLAY,
170-
span,
171-
"warning: type does not have a proper discriminant. It may be indistinguishable when deserialized.",
172-
None,
173-
"help: add an enum with at least as many variants as there are struct definitions"
174-
);
175171
}
176172
}
177173

0 commit comments

Comments
 (0)