From 448fc1470ddc975a50ddcea470f576a2db1db382 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 9 Oct 2022 11:29:40 +0200 Subject: [PATCH 1/4] Note that it is not a breaking change to make an `unsafe` function safe --- src/doc/src/reference/semver.md | 69 +++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index fccbd02f97e..324cad8804c 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -88,6 +88,7 @@ considered incompatible. * [Possibly-breaking: introducing a new function type parameter](#fn-generic-new) * [Minor: generalizing a function to use generics (supporting original type)](#fn-generalize-compatible) * [Major: generalizing a function to use generics with type mismatch](#fn-generalize-mismatch) + * [Minor: making an `unsafe` function safe](#fn-unsafe-safe) * Attributes * [Major: switching from `no_std` support to requiring `std`](#attr-no-std-to-std) * [Major: adding `non_exhaustive` to an existing enum, variant, or struct with no private fields](#attr-adding-non-exhaustive) @@ -1080,6 +1081,73 @@ fn main() { } ``` + +### Minor: making an `unsafe` function safe + +It is not a breaking change to make a previously `unsafe` function safe, as in +the example below. + +Going the other way (making a safe function `unsafe`) is a breaking change. + +```rust,ignore +// MINOR CHANGE + +/////////////////////////////////////////////////////////// +// Before +pub unsafe fn foo() {} + +/////////////////////////////////////////////////////////// +// After +pub fn foo() {} + +/////////////////////////////////////////////////////////// +// Example use of the library that will safely work. +use updated_crate::foo; + +unsafe fn bar(f: unsafe fn()) { + f() +} + +fn main() { + unsafe { foo() }; // The `unused_unsafe` lint will trigger here + unsafe { bar(foo) }; +} +``` + +Making an a previously `unsafe` associated function or method on structs / +enums safe is also a minor change, while the same is not true for associated +function on traits: + +```rust,ignore +// MAJOR CHANGE + +/////////////////////////////////////////////////////////// +// Before +pub trait Foo { + unsafe fn foo(); +} + +/////////////////////////////////////////////////////////// +// After +pub trait Foo { + fn foo(); +} + +/////////////////////////////////////////////////////////// +// Example usage that will break. +use updated_crate::Foo; + +struct Bar; + +impl Foo for Bar { + unsafe fn foo() {} // Error: method `foo` has an incompatible type for trait +} +``` + +Note that local crates that have specified `#![deny(warnings)]` (which is an +[anti-pattern][deny warnings]) will break, since they've explicitly opted out +of Rust's stability guarantees. + ### Major: switching from `no_std` support to requiring `std` @@ -1487,3 +1555,4 @@ document what your commitments are. [SemVer]: https://semver.org/ [struct literal]: ../../reference/expressions/struct-expr.html [wildcard patterns]: ../../reference/patterns.html#wildcard-pattern +[deny warnings]: https://rust-unofficial.github.io/patterns/anti_patterns/deny-warnings.html From 885a416b47438f6730b310973fd8fd3e7ed08b90 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 12 Oct 2022 21:48:31 +0200 Subject: [PATCH 2/4] Do not take a stance on #![deny(warnings)] --- src/doc/src/reference/semver.md | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index 324cad8804c..37d974de323 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -88,7 +88,7 @@ considered incompatible. * [Possibly-breaking: introducing a new function type parameter](#fn-generic-new) * [Minor: generalizing a function to use generics (supporting original type)](#fn-generalize-compatible) * [Major: generalizing a function to use generics with type mismatch](#fn-generalize-mismatch) - * [Minor: making an `unsafe` function safe](#fn-unsafe-safe) + * [Possibly-breaking: making an `unsafe` function safe](#fn-unsafe-safe) * Attributes * [Major: switching from `no_std` support to requiring `std`](#attr-no-std-to-std) * [Major: adding `non_exhaustive` to an existing enum, variant, or struct with no private fields](#attr-adding-non-exhaustive) @@ -1082,10 +1082,12 @@ fn main() { ``` -### Minor: making an `unsafe` function safe +### Possibly-breaking: making an `unsafe` function safe -It is not a breaking change to make a previously `unsafe` function safe, as in -the example below. +A previously `unsafe` function can be made safe without breaking code. Note +however that it will likely cause the [`unused_unsafe`][unused_unsafe] lint +to trigger as in the example below, which will cause local crates that have +specified `#![deny(warnings)]` to stop compiling. Going the other way (making a safe function `unsafe`) is a breaking change. @@ -1101,7 +1103,7 @@ pub unsafe fn foo() {} pub fn foo() {} /////////////////////////////////////////////////////////// -// Example use of the library that will safely work. +// Example use of the library that will trigger a lint. use updated_crate::foo; unsafe fn bar(f: unsafe fn()) { @@ -1144,10 +1146,6 @@ impl Foo for Bar { } ``` -Note that local crates that have specified `#![deny(warnings)]` (which is an -[anti-pattern][deny warnings]) will break, since they've explicitly opted out -of Rust's stability guarantees. - ### Major: switching from `no_std` support to requiring `std` @@ -1555,4 +1553,4 @@ document what your commitments are. [SemVer]: https://semver.org/ [struct literal]: ../../reference/expressions/struct-expr.html [wildcard patterns]: ../../reference/patterns.html#wildcard-pattern -[deny warnings]: https://rust-unofficial.github.io/patterns/anti_patterns/deny-warnings.html +[unused_unsafe]: ../../rustc/lints/listing/warn-by-default.html#unused-unsafe From 1351ff73b5be0e3d0a915a6bce4fdb3d6ddfcf61 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 12 Oct 2022 21:50:05 +0200 Subject: [PATCH 3/4] Fix typo Co-authored-by: Eric Huss --- src/doc/src/reference/semver.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index 37d974de323..6c912048ca9 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -1116,8 +1116,8 @@ fn main() { } ``` -Making an a previously `unsafe` associated function or method on structs / -enums safe is also a minor change, while the same is not true for associated +Making a previously `unsafe` associated function or method on structs / enums +safe is also a minor change, while the same is not true for associated function on traits: ```rust,ignore From 8782f799dfb6ec63e9e87131873a3cf89c25369a Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 9 May 2023 12:32:19 -0700 Subject: [PATCH 4/4] Clarify unsafe to safe function qualifier change. --- src/doc/src/reference/semver.md | 42 +++++++-------------------------- 1 file changed, 9 insertions(+), 33 deletions(-) diff --git a/src/doc/src/reference/semver.md b/src/doc/src/reference/semver.md index 6c912048ca9..5ce9b5dd4df 100644 --- a/src/doc/src/reference/semver.md +++ b/src/doc/src/reference/semver.md @@ -88,7 +88,7 @@ considered incompatible. * [Possibly-breaking: introducing a new function type parameter](#fn-generic-new) * [Minor: generalizing a function to use generics (supporting original type)](#fn-generalize-compatible) * [Major: generalizing a function to use generics with type mismatch](#fn-generalize-mismatch) - * [Possibly-breaking: making an `unsafe` function safe](#fn-unsafe-safe) + * [Minor: making an `unsafe` function safe](#fn-unsafe-safe) * Attributes * [Major: switching from `no_std` support to requiring `std`](#attr-no-std-to-std) * [Major: adding `non_exhaustive` to an existing enum, variant, or struct with no private fields](#attr-adding-non-exhaustive) @@ -1082,12 +1082,14 @@ fn main() { ``` -### Possibly-breaking: making an `unsafe` function safe +### Minor: making an `unsafe` function safe -A previously `unsafe` function can be made safe without breaking code. Note -however that it will likely cause the [`unused_unsafe`][unused_unsafe] lint -to trigger as in the example below, which will cause local crates that have -specified `#![deny(warnings)]` to stop compiling. +A previously `unsafe` function can be made safe without breaking code. + +Note however that it may cause the [`unused_unsafe`][unused_unsafe] lint to +trigger as in the example below, which will cause local crates that have +specified `#![deny(warnings)]` to stop compiling. Per [introducing new +lints](#new-lints), it is allowed for updates to introduce new warnings. Going the other way (making a safe function `unsafe`) is a breaking change. @@ -1118,33 +1120,7 @@ fn main() { Making a previously `unsafe` associated function or method on structs / enums safe is also a minor change, while the same is not true for associated -function on traits: - -```rust,ignore -// MAJOR CHANGE - -/////////////////////////////////////////////////////////// -// Before -pub trait Foo { - unsafe fn foo(); -} - -/////////////////////////////////////////////////////////// -// After -pub trait Foo { - fn foo(); -} - -/////////////////////////////////////////////////////////// -// Example usage that will break. -use updated_crate::Foo; - -struct Bar; - -impl Foo for Bar { - unsafe fn foo() {} // Error: method `foo` has an incompatible type for trait -} -``` +function on traits (see [any change to trait item signatures](#trait-item-signature)). ### Major: switching from `no_std` support to requiring `std`