@@ -88,6 +88,7 @@ considered incompatible.
88
88
* [ Possibly-breaking: introducing a new function type parameter] ( #fn-generic-new )
89
89
* [ Minor: generalizing a function to use generics (supporting original type)] ( #fn-generalize-compatible )
90
90
* [ Major: generalizing a function to use generics with type mismatch] ( #fn-generalize-mismatch )
91
+ * [ Minor: making an ` unsafe ` function safe] ( #fn-unsafe-safe )
91
92
* Attributes
92
93
* [ Major: switching from ` no_std ` support to requiring ` std ` ] ( #attr-no-std-to-std )
93
94
* [ 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() {
1080
1081
}
1081
1082
```
1082
1083
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
+
1083
1151
<a id =" attr-no-std-to-std " ></a >
1084
1152
### Major: switching from ` no_std ` support to requiring ` std `
1085
1153
@@ -1487,3 +1555,4 @@ document what your commitments are.
1487
1555
[ SemVer ] : https://semver.org/
1488
1556
[ struct literal ] : ../../reference/expressions/struct-expr.html
1489
1557
[ wildcard patterns ] : ../../reference/patterns.html#wildcard-pattern
1558
+ [ deny warnings ] : https://rust-unofficial.github.io/patterns/anti_patterns/deny-warnings.html
0 commit comments