Skip to content
This repository was archived by the owner on Apr 5, 2024. It is now read-only.

Commit b1b0762

Browse files
committed
Fixed error reporting on field changes to structs.
1 parent 023f943 commit b1b0762

File tree

4 files changed

+120
-23
lines changed

4 files changed

+120
-23
lines changed

src/changes.rs

Lines changed: 109 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -306,11 +306,11 @@ pub enum ChangeType<'tcx> {
306306
/// A possibly public field has been added to a variant or struct.
307307
///
308308
/// This also records whether all fields are public were public before the change.
309-
VariantFieldAdded { public: bool, total_public: bool },
309+
VariantFieldAdded { public: bool, total_public: bool, is_enum: bool },
310310
/// A possibly public field has been removed from a variant or struct.
311311
///
312-
/// This also records whether all fields are public were public before the change.
313-
VariantFieldRemoved { public: bool, total_public: bool },
312+
/// This also records whether all fields were public before the change.
313+
VariantFieldRemoved { public: bool, total_public: bool, is_enum: bool },
314314
/// A variant or struct has changed it's style.
315315
///
316316
/// The style could have been changed from a tuple variant/struct to a regular
@@ -319,6 +319,7 @@ pub enum ChangeType<'tcx> {
319319
VariantStyleChanged {
320320
now_struct: bool,
321321
total_private: bool,
322+
is_enum: bool,
322323
},
323324
/// A function has changed it's constness.
324325
FnConstChanged { now_const: bool },
@@ -373,8 +374,10 @@ impl<'tcx> ChangeType<'tcx> {
373374
TypeParameterRemoved { .. } |
374375
VariantAdded |
375376
VariantRemoved |
376-
VariantFieldAdded { .. } | // TODO: this (and the two below) appear wrong
377-
VariantFieldRemoved { .. } |
377+
VariantFieldAdded { public: true, .. } |
378+
VariantFieldAdded { public: false, total_public: true, .. } |
379+
VariantFieldRemoved { public: true, .. } |
380+
VariantFieldRemoved { public: false, is_enum: true, .. } |
378381
VariantStyleChanged { .. } |
379382
TypeChanged { .. } |
380383
FnConstChanged { now_const: false } |
@@ -396,6 +399,8 @@ impl<'tcx> ChangeType<'tcx> {
396399
StaticMutabilityChanged { now_mut: true } |
397400
VarianceLoosened |
398401
TypeParameterAdded { defaulted: true } |
402+
VariantFieldAdded { public: false, .. } |
403+
VariantFieldRemoved { public: false, .. } |
399404
FnConstChanged { now_const: true } => NonBreaking,
400405
}
401406
}
@@ -477,13 +482,13 @@ on said enum can become non-exhaustive."
477482
to the removed variant is rendered invalid."
478483
}
479484
VariantFieldAdded { .. } => {
480-
"Adding a field to an enum variant is breaking, as matches on the variant are
481-
invalidated. In case of structs, this only holds for public fields, or the
482-
first private field being added."
485+
"Adding a field to an enum variant or struct is breaking, as matches on the
486+
variant or struct are invalidated. In case of structs, this only holds for
487+
public fields, or the first private field being added."
483488
}
484489
VariantFieldRemoved { .. } => {
485-
"Removing a field from an enum variant is breaking, as matches on the variant
486-
are invalidated. In case of structs, this only holds for public fields."
490+
"Removing a field from an enum variant or struct is breaking, as matches on the
491+
variant are invalidated. In case of structs, this only holds for public fields."
487492
}
488493
VariantStyleChanged { .. } => {
489494
"Changing the style of a variant is a breaking change, since most old
@@ -616,51 +621,123 @@ impl<'a> fmt::Display for ChangeType<'a> {
616621
VariantFieldAdded {
617622
public: true,
618623
total_public: true,
619-
} => "public variant field added to variant with no private fields",
624+
is_enum: true,
625+
} => "public field added to variant with no private fields",
626+
VariantFieldAdded {
627+
public: true,
628+
total_public: true,
629+
is_enum: false,
630+
} => "public field added to struct with no private fields",
631+
VariantFieldAdded {
632+
public: true,
633+
total_public: false,
634+
is_enum: true,
635+
} => "public field added to variant with private fields",
620636
VariantFieldAdded {
621637
public: true,
622638
total_public: false,
623-
} => "public variant field added to variant with private fields",
639+
is_enum: false,
640+
} => "public field added to struct with private fields",
641+
VariantFieldAdded {
642+
public: false,
643+
total_public: true,
644+
is_enum: true,
645+
} => "private field added to variant with no private fields",
624646
VariantFieldAdded {
625647
public: false,
626648
total_public: true,
627-
} => "variant field added to variant with no private fields",
649+
is_enum: false,
650+
} => "private field added to struct with no private fields",
628651
VariantFieldAdded {
629652
public: false,
630653
total_public: false,
631-
} => "variant field added to variant with private fields",
654+
is_enum: true,
655+
} => "private field added to variant with private fields",
656+
VariantFieldAdded {
657+
public: false,
658+
total_public: false,
659+
is_enum: false,
660+
} => "private field added to struct with private fields",
632661
VariantFieldRemoved {
633662
public: true,
634663
total_public: true,
635-
} => "public variant field removed from variant with no private fields",
664+
is_enum: true,
665+
} => "public field removed from variant with no private fields",
666+
VariantFieldRemoved {
667+
public: true,
668+
total_public: true,
669+
is_enum: false,
670+
} => "public field removed from struct with no private fields",
671+
VariantFieldRemoved {
672+
public: true,
673+
total_public: false,
674+
is_enum: true
675+
} => "public field removed from variant with private fields",
636676
VariantFieldRemoved {
637677
public: true,
638678
total_public: false,
639-
} => "public variant field removed from variant with private fields",
679+
is_enum: false,
680+
} => "public field removed from struct with private fields",
640681
VariantFieldRemoved {
641682
public: false,
642683
total_public: true,
643-
} => "variant field removed from variant with no private fields",
684+
is_enum: true,
685+
} => "private field removed from variant with no private fields",
686+
VariantFieldRemoved {
687+
public: false,
688+
total_public: true,
689+
is_enum: false,
690+
} => "private field removed from struct with no private fields",
644691
VariantFieldRemoved {
645692
public: false,
646693
total_public: false,
647-
} => "variant field removed from variant with private fields",
694+
is_enum: true,
695+
} => "private field removed from variant with private fields",
696+
VariantFieldRemoved {
697+
public: false,
698+
total_public: false,
699+
is_enum: false,
700+
} => "private field removed from struct with private fields",
648701
VariantStyleChanged {
649702
now_struct: true,
650703
total_private: true,
704+
is_enum: true,
651705
} => "variant with no public fields changed to a struct variant",
706+
VariantStyleChanged {
707+
now_struct: true,
708+
total_private: true,
709+
is_enum: false,
710+
} => "tuple struct with no public fields changed to a regular struct",
652711
VariantStyleChanged {
653712
now_struct: true,
654713
total_private: false,
655-
} => "variant changed to a struct variant",
714+
is_enum: true,
715+
} => "variant with public fields changed to a struct variant",
716+
VariantStyleChanged {
717+
now_struct: true,
718+
total_private: false,
719+
is_enum: false,
720+
} => "tuple struct with public fields changed to a regular struct",
656721
VariantStyleChanged {
657722
now_struct: false,
658723
total_private: true,
724+
is_enum: true,
659725
} => "variant with no public fields changed to a tuple variant",
726+
VariantStyleChanged {
727+
now_struct: false,
728+
total_private: true,
729+
is_enum: false,
730+
} => "struct with no public fields changed to a tuple struct",
731+
VariantStyleChanged {
732+
now_struct: false,
733+
total_private: false,
734+
is_enum: true,
735+
} => "variant with public fields changed to a tuple variant",
660736
VariantStyleChanged {
661737
now_struct: false,
662738
total_private: false,
663-
} => "variant changed to a tuple variant",
739+
is_enum: false,
740+
} => "struct with public fields changed to a tuple struct",
664741
FnConstChanged { now_const: true } => "fn item made const",
665742
FnConstChanged { now_const: false } => "fn item made non-const",
666743
MethodSelfChanged { now_self: true } => "added self-argument to method",
@@ -1210,14 +1287,17 @@ pub mod tests {
12101287
VariantFieldAdded {
12111288
public: bool,
12121289
total_public: bool,
1290+
is_enum: bool,
12131291
},
12141292
VariantFieldRemoved {
12151293
public: bool,
12161294
total_public: bool,
1295+
is_enum: bool,
12171296
},
12181297
VariantStyleChanged {
12191298
now_struct: bool,
12201299
total_private: bool,
1300+
is_enum: bool,
12211301
},
12221302
FnConstChanged {
12231303
now_const: bool,
@@ -1255,23 +1335,29 @@ pub mod tests {
12551335
ChangeType_::VariantFieldAdded {
12561336
public,
12571337
total_public,
1338+
is_enum,
12581339
} => VariantFieldAdded {
12591340
public,
12601341
total_public,
1342+
is_enum,
12611343
},
12621344
ChangeType_::VariantFieldRemoved {
12631345
public,
12641346
total_public,
1347+
is_enum,
12651348
} => VariantFieldRemoved {
12661349
public,
12671350
total_public,
1351+
is_enum,
12681352
},
12691353
ChangeType_::VariantStyleChanged {
12701354
now_struct,
12711355
total_private,
1356+
is_enum,
12721357
} => VariantStyleChanged {
12731358
now_struct,
12741359
total_private,
1360+
is_enum,
12751361
},
12761362
ChangeType_::FnConstChanged { now_const } => FnConstChanged { now_const },
12771363
ChangeType_::MethodSelfChanged { now_self } => MethodSelfChanged { now_self },
@@ -1312,14 +1398,17 @@ pub mod tests {
13121398
VariantFieldAdded {
13131399
public: b1,
13141400
total_public: b2,
1401+
is_enum: b2,
13151402
},
13161403
VariantFieldRemoved {
13171404
public: b1,
13181405
total_public: b2,
1406+
is_enum: b2,
13191407
},
13201408
VariantStyleChanged {
13211409
now_struct: b1,
13221410
total_private: b2,
1411+
is_enum: b2,
13231412
},
13241413
FnConstChanged { now_const: b1 },
13251414
MethodSelfChanged { now_self: b1 },

src/traverse.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,11 @@ fn diff_adts(changes: &mut ChangeSet, id_mapping: &mut IdMapping, tcx: TyCtxt, o
420420
_ => return,
421421
};
422422

423+
let is_enum = match old {
424+
Def(Enum, _) => true,
425+
_ => false,
426+
};
427+
423428
let mut variants = BTreeMap::new();
424429
let mut fields = BTreeMap::new();
425430

@@ -457,6 +462,7 @@ fn diff_adts(changes: &mut ChangeSet, id_mapping: &mut IdMapping, tcx: TyCtxt, o
457462
let c = ChangeType::VariantStyleChanged {
458463
now_struct: new.ctor_kind == CtorKind::Fictive,
459464
total_private,
465+
is_enum,
460466
};
461467
changes.add_change(c, old_def_id, Some(tcx.def_span(new.def_id)));
462468

@@ -486,13 +492,15 @@ fn diff_adts(changes: &mut ChangeSet, id_mapping: &mut IdMapping, tcx: TyCtxt, o
486492
let c = ChangeType::VariantFieldRemoved {
487493
public: o.vis == Public,
488494
total_public,
495+
is_enum,
489496
};
490497
changes.add_change(c, old_def_id, Some(tcx.def_span(o.did)));
491498
}
492499
(None, Some(n)) => {
493500
let c = ChangeType::VariantFieldAdded {
494501
public: n.vis == Public,
495502
total_public,
503+
is_enum,
496504
};
497505
changes.add_change(c, old_def_id, Some(tcx.def_span(n.did)));
498506
}

tests/cases/enums/stdout

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,12 @@ warning: variant with no public fields changed to a struct variant (breaking)
9393
|
9494
23 | Efg { f: u8 },
9595
| ^^^^^^^^^^^^^
96-
warning: variant field removed from variant with private fields (breaking)
96+
warning: private field removed from variant with private fields (breaking)
9797
--> enums/old.rs:25:11
9898
|
9999
25 | Ghi { f: u8 },
100100
| ^^^^^
101-
warning: variant field added to variant with private fields (breaking)
101+
note: private field added to variant with private fields (non-breaking)
102102
--> enums/new.rs:25:11
103103
|
104104
25 | Ghi { g: u8 },

tests/cases/structs/stdout

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ error: breaking changes in `Hij`
7171
28 | | }
7272
| |_^
7373
|
74-
warning: variant with no public fields changed to a struct variant (breaking)
74+
warning: tuple struct with no public fields changed to a regular struct (breaking)
7575
--> structs/new.rs:26:1
7676
|
7777
26 | / pub struct Hij {

0 commit comments

Comments
 (0)