@@ -19,7 +19,7 @@ an opt-in language feature that prevents common memory safety issues by running
1919extra compile-time safety checks and emitting diagnostics.
2020
2121This document describes the way Swift/C++ interoperability works when strict
22- safe mode is enabled in Swift.
22+ safety mode is enabled in Swift.
2323
2424* * *
2525
@@ -42,7 +42,7 @@ Swift provides memory safety with a combination of language affordances and runt
4242However, Swift also deliberately includes some unsafe constructs, such as the ` UnsafePointer ` and ` UnsafeMutablePointer `
4343types in the standard library.
4444In some cases, Swift needs additional information that is not present in the C++ type and API declarations
45- to safely interface with them. This document describes how such code needs to be annotated.
45+ to safely interface with them. This document describes how such code needs to be annotated so that it can be used in strict safety mode .
4646
4747### Annotating Foreign Types
4848
@@ -52,16 +52,16 @@ pointers will be imported as unsafe (section [Working with C++ references and vi
5252explains this in more detail.) Under the strict memory safe mode, the compiler will flip the polarity and
5353treat all types that are not known to be safe as unsafe, and will diagnose uses of them. In this section,
5454we will show how to annotate unsafe C++ types so that they can be accessed safely and correctly from Swift.
55- Note that the features here are agnostic to whether strictly-safe mode is on or off. When the strictly safe
56- mode is on, the compiler warnings can serve as a guide to properly annotate C++ types and also help ensure
57- that the code doesn't use unsafe APIs anywhere. When the strictly-memory-safe mode is off, it is still
55+ Note that the features here are agnostic to whether strict safety mode is on or off. When the strict safety
56+ mode is on, the compiler diagnostics can serve as a guide on how to properly annotate C++ types, and also help ensure
57+ that the code doesn't use unsafe APIs anywhere. When the strict safety mode is turned off, it is still
5858recommended to adopt these annotation wherever appropriate, especially on C++ types that are potentially
59- lifetime dependent on other objects.
59+ dependent on the lifetimes of other objects.
6060
61- Under strictly-memory-safe mode the built-in integral types like ` int ` , some standard library types like ` std::string ` ,
62- and aggregate types built from other safe types are considered safe. Whereas all other unannotated types
61+ Under the strict safety mode, built-in numeric types like ` int ` , some standard library types like ` std::string ` ,
62+ and aggregate types built from other safe types are considered safe. All other unannotated types
6363are considered unsafe. Let's see what happens when we are trying to use an unannotated type in
64- strictly-safe mode. Consider the following C++ type and APIs:
64+ strict safety mode. Consider the following C++ type and APIs:
6565
6666``` c++
6767class StringRef {
@@ -88,13 +88,13 @@ func getFileName(_ path: borrowing std.string) -> StringRef {
8888
8989Building this code will emit a warning that the ` fileName ` call is unsafe because
9090it references the unsafe type ` StringRef ` . Swift considers ` StringRef ` unsafe because
91- it has a pointer member. Types like ` StringRef ` can dangle, so we need to take extra
92- care using them, making sure the referenced buffer outlives the ` StringRef ` object.
91+ it has a pointer member. Pointers in types like ` StringRef ` can dangle, so we need to take extra
92+ care that the buffer they point to outlives the ` StringRef ` object they are encapsulated by .
9393
9494Swift's [ non-escapable types] ( https://github.com/swiftlang/swift-evolution/blob/main/proposals/0446-non-escapable.md )
9595can also have lifetime dependencies, just like ` StringRef ` . However, the Swift compiler
9696can track these dependencies and enforce safety at compile time. To import ` StringRef `
97- as a safe type we need to mark it as a non-escapable type, we can annotate the class
97+ as a safe type, we need to mark it as a non-escapable type by annotating the class
9898definition:
9999
100100``` c++
@@ -107,7 +107,7 @@ emits a warning about using an unsafe type.
107107### Annotating C++ APIs
108108
109109Building the code again will emit a new diagnostic for the `fileName` function about
110- missing lifetime annotations. Functions returning non-escapable types need annotations
110+ missing lifetime annotations. C and C++ functions that return non-escapable types need annotations
111111to describe their lifetime contracts via [lifetimebound](https://clang.llvm.org/docs/AttributeReference.html#id11)
112112and [lifetime_capture_by](https://clang.llvm.org/docs/AttributeReference.html#lifetime-capture-by) annotations.
113113
@@ -118,7 +118,7 @@ StringRef fileName(const std::string& normalizedPath [[clang::lifetimebound]]);
118118Adding this annotation to ` fileName ` indicates that the returned ` StringRef ` value has the
119119same lifetime as the argument of the ` fileName ` function.
120120
121- Building the project again reveals a lifetime error in the Swift function:
121+ Building the project again reveals a lifetime error in the Swift function that calls ` fileName ` :
122122
123123``` swift
124124func getFileName (_ path : borrowing std.string) -> StringRef {
@@ -134,7 +134,7 @@ We can fix this error by pushing the task of normalizing a path to the callee:
134134
135135``` swift
136136// Path needs to be normalized.
137- func getFileName (_ path : borrowing std.string) -> StringRef {
137+ func getFileName (_ normalizedPath : borrowing std.string) -> StringRef {
138138 return fileName (normalizedPath)
139139}
140140```
@@ -254,9 +254,9 @@ struct SWIFT_NONESCAPABLE View {
254254```
255255
256256In this example, the object initialized by the ` View ` constructor has the same
257- lifetime as the input argument of the constructor.
257+ lifetime as the argument ` p ` of the constructor.
258258
259- In case the attribute is after the method signature, the returned object has
259+ When the attribute is written after the method signature, the returned object has
260260the same lifetime as the implicit ` this ` parameter.
261261
262262``` c++
@@ -393,6 +393,6 @@ using IntVec = std::vector<int>;
393393| ` IntSpan changeSpan(IntVec& x [[clang::lifetimebound]]); ` | ` @lifetime(x) func changeSpan(_ x: borrowing IntVec) -> Span<Int32> ` |
394394| ` IntSpan Owner::getSpan() [[clang::lifetimebound]]; ` | ` @lifetime(self) func getSpan() -> Span<Int32> ` |
395395
396- These transformations only support top level ` std::span ` s. The compiler
397- currently does not transform nested ` std::span ` s. A ` std::span ` of a non-const
398- type ` T ` is transformed to ` MutableSpan<T> ` on the Swift wide .
396+ These transformations only support top- level ` std::span ` s. The compiler
397+ currently does not transform nested ` std::span ` s. A ` std::span<T> ` of a non-const
398+ type ` T ` is transformed to ` MutableSpan<T> ` on the Swift side .
0 commit comments