Skip to content

Commit 092b1c0

Browse files
committed
Expand the collation of unsafe constructs to all declarations that can handle it
Drive the strict-safety diagnostics for a particular declaration from primary type checking for declarations, so any memory-safety-related diagnostics will only be emitted for the primary files. This also brings them together as notes under a single warning for each declaration.
1 parent c280eb0 commit 092b1c0

File tree

5 files changed

+24
-22
lines changed

5 files changed

+24
-22
lines changed

lib/Sema/TypeCheckAvailability.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ void diagnoseUnsafeUse(const UnsafeUse &use, bool asNote = false);
280280
/// declaration, if there are any.
281281
void diagnoseUnsafeUsesIn(const Decl *decl);
282282

283-
284283
} // namespace swift
285284

286285
#endif // SWIFT_SEMA_TYPE_CHECK_AVAILABILITY_H

lib/Sema/TypeCheckDeclPrimary.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2348,8 +2348,21 @@ class DeclChecker : public DeclVisitor<DeclChecker> {
23482348
{ });
23492349
}
23502350
}
2351+
2352+
// Diagnose any uses of unsafe constructs within this declaration.
2353+
if (!hasUnsafeCheckingOutsideOfPrimary(decl))
2354+
diagnoseUnsafeUsesIn(decl);
23512355
}
23522356

2357+
/// Determine whether @unsafe checking for this declaration occurs outside
2358+
/// of "primary" declaration checking, e.g., with the request that
2359+
/// type-checks a function body.
2360+
static bool hasUnsafeCheckingOutsideOfPrimary(const Decl *decl) {
2361+
if (auto func = dyn_cast<AbstractFunctionDecl>(decl))
2362+
return func->hasBody();
2363+
2364+
return false;
2365+
}
23532366

23542367
//===--------------------------------------------------------------------===//
23552368
// Visit Methods.

lib/Sema/TypeCheckUnsafe.cpp

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -87,16 +87,6 @@ static void suggestUnsafeMarkerOnConformance(
8787
).fixItInsert(decl->getAttributeInsertionLoc(false), "@unsafe ");
8888
}
8989

90-
static bool shouldDeferUnsafeUseIn(const Decl *decl) {
91-
if (auto func = dyn_cast_or_null<AbstractFunctionDecl>(decl)) {
92-
if (func->hasBody()) {
93-
return true;
94-
}
95-
}
96-
97-
return false;
98-
}
99-
10090
/// Retrieve the extra information
10191
static SourceFileExtras &getSourceFileExtrasFor(const Decl *decl) {
10292
auto dc = decl->getDeclContext();
@@ -112,7 +102,7 @@ void swift::diagnoseUnsafeUse(const UnsafeUse &use, bool asNote) {
112102
use.getKind() == UnsafeUse::CallToUnsafe) {
113103
auto [enclosingDecl, _] = enclosingContextForUnsafe(
114104
use.getLocation(), use.getDeclContext());
115-
if (enclosingDecl && shouldDeferUnsafeUseIn(enclosingDecl)) {
105+
if (enclosingDecl) {
116106
getSourceFileExtrasFor(enclosingDecl).unsafeUses[enclosingDecl]
117107
.push_back(use);
118108
return;

test/Unsafe/unsafe-suppression.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class NonSendable { }
9191

9292

9393
@unsafe
94-
struct UnsafeOuter { // expected-note{{unsafe struct 'UnsafeOuter' declared here}}
94+
struct UnsafeOuter {
9595
func f(_: UnsafeType) { } // okay
9696

9797
@unsafe func g(_ y: UnsafeType) {
@@ -100,8 +100,8 @@ struct UnsafeOuter { // expected-note{{unsafe struct 'UnsafeOuter' declared here
100100
}
101101
}
102102

103-
// expected-note@+1{{make extension of struct 'UnsafeOuter' @unsafe to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
104-
extension UnsafeOuter { // expected-warning{{reference to unsafe struct 'UnsafeOuter' [Unsafe]}}
103+
// expected-warning@+1{{extension of struct 'UnsafeOuter' involves unsafe code; use '@unsafe' to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
104+
extension UnsafeOuter { // expected-note{{reference to unsafe struct 'UnsafeOuter'}}
105105
func h(_: UnsafeType) { }
106106
}
107107

test/Unsafe/unsafe.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,12 @@ struct SuperHolder {
6161
// -----------------------------------------------------------------------
6262
// Inheritance of @unsafe
6363
// -----------------------------------------------------------------------
64-
@unsafe class UnsafeSuper { // expected-note 4{{'UnsafeSuper' declared here}}
64+
@unsafe class UnsafeSuper { // expected-note{{'UnsafeSuper' declared here}}
6565
func f() { }
6666
};
6767

68-
class UnsafeSub: UnsafeSuper { } // expected-warning{{reference to unsafe class 'UnsafeSuper'}}
69-
// expected-note@-1{{make class 'UnsafeSub' @unsafe to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
68+
class UnsafeSub: UnsafeSuper { } // expected-warning{{class 'UnsafeSub' involves unsafe code; use '@unsafe' to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
69+
// expected-note@-1{{reference to unsafe class 'UnsafeSuper'}}
7070

7171
// -----------------------------------------------------------------------
7272
// Declaration references
@@ -90,13 +90,13 @@ func testMe(
9090
// -----------------------------------------------------------------------
9191
// Various declaration kinds
9292
// -----------------------------------------------------------------------
93-
// expected-note@+1{{make type alias 'SuperUnsafe' @unsafe to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
94-
typealias SuperUnsafe = UnsafeSuper // expected-warning{{reference to unsafe class 'UnsafeSuper' [Unsafe]}}
93+
// expected-warning@+1{{type alias 'SuperUnsafe' involves unsafe code; use '@unsafe' to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
94+
typealias SuperUnsafe = UnsafeSuper // expected-note{{reference to unsafe class 'UnsafeSuper'}}
9595
@unsafe typealias SuperUnsafe2 = UnsafeSuper
9696

9797
enum HasUnsafeThings {
98-
// expected-note@+1{{make enum case 'one' @unsafe to indicate that its use is not memory-safe}}
99-
case one(UnsafeSuper) // expected-warning{{reference to unsafe class 'UnsafeSuper' [Unsafe]}}
98+
// expected-warning@+1{{enum case 'one' involves unsafe code; use '@unsafe' to indicate that its use is not memory-safe}}{{1-1=@unsafe }}
99+
case one(UnsafeSuper) // expected-note{{reference to unsafe class 'UnsafeSuper'}}
100100

101101
@unsafe case two(UnsafeSuper)
102102
}

0 commit comments

Comments
 (0)