@@ -88,6 +88,7 @@ considered incompatible.
8888 * [ Possibly-breaking: introducing a new function type parameter] ( #fn-generic-new )
8989 * [ Minor: generalizing a function to use generics (supporting original type)] ( #fn-generalize-compatible )
9090 * [ Major: generalizing a function to use generics with type mismatch] ( #fn-generalize-mismatch )
91+ * [ Minor: making an ` unsafe ` function safe] ( #fn-unsafe-safe )
9192 * Attributes
9293 * [ Major: switching from ` no_std ` support to requiring ` std ` ] ( #attr-no-std-to-std )
9394 * [ 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() {
10801081}
10811082```
10821083
1084+ <a id =" fn-unsafe-safe " ></a >
1085+ ### Minor: making an ` unsafe ` function safe
1086+
1087+ It is not a breaking change to make a previously ` unsafe ` function safe, as in
1088+ the example below.
1089+
1090+ Going the other way (making a safe function ` unsafe ` ) is a breaking change.
1091+
1092+ ``` rust,ignore
1093+ // MINOR CHANGE
1094+
1095+ ///////////////////////////////////////////////////////////
1096+ // Before
1097+ pub unsafe fn foo() {}
1098+
1099+ ///////////////////////////////////////////////////////////
1100+ // After
1101+ pub fn foo() {}
1102+
1103+ ///////////////////////////////////////////////////////////
1104+ // Example use of the library that will safely work.
1105+ use updated_crate::foo;
1106+
1107+ unsafe fn bar(f: unsafe fn()) {
1108+ f()
1109+ }
1110+
1111+ fn main() {
1112+ unsafe { foo() }; // The `unused_unsafe` lint will trigger here
1113+ unsafe { bar(foo) };
1114+ }
1115+ ```
1116+
1117+ Making an a previously ` unsafe ` associated function or method on structs /
1118+ enums safe is also a minor change, while the same is not true for associated
1119+ function on traits:
1120+
1121+ ``` rust,ignore
1122+ // MAJOR CHANGE
1123+
1124+ ///////////////////////////////////////////////////////////
1125+ // Before
1126+ pub trait Foo {
1127+ unsafe fn foo();
1128+ }
1129+
1130+ ///////////////////////////////////////////////////////////
1131+ // After
1132+ pub trait Foo {
1133+ fn foo();
1134+ }
1135+
1136+ ///////////////////////////////////////////////////////////
1137+ // Example usage that will break.
1138+ use updated_crate::Foo;
1139+
1140+ struct Bar;
1141+
1142+ impl Foo for Bar {
1143+ unsafe fn foo() {} // Error: method `foo` has an incompatible type for trait
1144+ }
1145+ ```
1146+
1147+ Note that local crates that have specified ` #![deny(warnings)] ` (which is an
1148+ [ anti-pattern] [ deny warnings ] ) will break, since they've explicitly opted out
1149+ of Rust's stability guarantees.
1150+
10831151<a id =" attr-no-std-to-std " ></a >
10841152### Major: switching from ` no_std ` support to requiring ` std `
10851153
@@ -1487,3 +1555,4 @@ document what your commitments are.
14871555[ SemVer ] : https://semver.org/
14881556[ struct literal ] : ../../reference/expressions/struct-expr.html
14891557[ wildcard patterns ] : ../../reference/patterns.html#wildcard-pattern
1558+ [ deny warnings ] : https://rust-unofficial.github.io/patterns/anti_patterns/deny-warnings.html
0 commit comments