From ff0a666f914eac124e20d0bc43234a667377b025 Mon Sep 17 00:00:00 2001 From: Predrag Gruevski <2348618+obi1kenobi@users.noreply.github.com> Date: Fri, 15 Jul 2022 20:43:16 -0400 Subject: [PATCH 1/3] Add "unit struct to normal struct" case to semver.md Changing a public unit struct to a normal struct is a breaking change that should require a major version bump. Adding an entry to the semver page in the reference to document this. --- src/doc/src/reference/semver.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index ee6962eafa5..cb3f920afcb 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -62,6 +62,7 @@ considered incompatible. * Structs * [Major: adding a private struct field when all current fields are public](#struct-add-private-field-when-public) * [Major: adding a public field when no private field exists](#struct-add-public-field-when-no-private) + * [Major: going from a unit struct to a normal struct, even if it has no fields](#struct-unit-to-normal) * [Minor: adding or removing private fields when at least one already exists](#struct-private-fields-with-private) * [Minor: going from a tuple struct with all private fields (with at least one field) to a normal struct, or vice versa](#struct-tuple-normal-with-private) * Enums @@ -273,6 +274,33 @@ Mitigation strategies: a struct to prevent users from using struct literal syntax, and instead provide a constructor method and/or [Default] implementation. + +### Major: going from a unit struct to a normal struct, even if it has no fields + +When constructing a normal struct using [struct literal] syntax, the curly braces +are required even if the struct has no fields. Changing a unit struct +to a normal struct will then break any code that attempted to construct +the unit struct using a [struct literal]. + +```rust,ignore +// MAJOR CHANGE + +/////////////////////////////////////////////////////////// +// Before +pub struct Foo; + +/////////////////////////////////////////////////////////// +// After +pub struct Foo {} + +/////////////////////////////////////////////////////////// +// Example usage that will break. +fn main() { + let x = Foo; // Error: expected value, found struct `Foo` + // ^^^ help: use struct literal syntax instead: `Foo {}` +} +``` + ### Minor: adding or removing private fields when at least one already exists From dc2399dd54b2d3ecc9428150e6de32fdc9a9a72b Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Sat, 16 Jul 2022 13:00:22 -0400 Subject: [PATCH 2/3] Import Foo in the example. --- src/doc/src/reference/semver.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index cb3f920afcb..110897d18a4 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -279,7 +279,7 @@ Mitigation strategies: When constructing a normal struct using [struct literal] syntax, the curly braces are required even if the struct has no fields. Changing a unit struct -to a normal struct will then break any code that attempted to construct +to a normal struct will then break any code that attempted to construct the unit struct using a [struct literal]. ```rust,ignore @@ -295,6 +295,8 @@ pub struct Foo {} /////////////////////////////////////////////////////////// // Example usage that will break. +use updated_crate::Foo; + fn main() { let x = Foo; // Error: expected value, found struct `Foo` // ^^^ help: use struct literal syntax instead: `Foo {}` From a2d103e82b9ec20309a3a51cd177838c32d5705c Mon Sep 17 00:00:00 2001 From: Predrag Gruevski Date: Tue, 19 Jul 2022 11:58:31 -0400 Subject: [PATCH 3/3] Clarify unit struct behavior when #[non_exhaustive]. --- src/doc/src/reference/semver.md | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index 110897d18a4..d0da109d08d 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -277,10 +277,13 @@ Mitigation strategies: ### Major: going from a unit struct to a normal struct, even if it has no fields -When constructing a normal struct using [struct literal] syntax, the curly braces -are required even if the struct has no fields. Changing a unit struct -to a normal struct will then break any code that attempted to construct -the unit struct using a [struct literal]. +A unit struct can be constructed using both `Unit` and `Unit {}` +[struct literal] syntax. However, the curly braces are mandatory for +normal structs, even ones with no fields. + +If the unit struct was not [`#[non_exhaustive]`][non_exhaustive], +changing it to a normal struct will break any code that constructs +it using a [struct literal] without the curly braces. ```rust,ignore // MAJOR CHANGE @@ -303,6 +306,10 @@ fn main() { } ``` +Mitigation strategies: +* Mark the unit struct [`#[non_exhaustive]`][non_exhaustive] when first + adding it, to make it impossible to construct outside of its own crate. + ### Minor: adding or removing private fields when at least one already exists