Skip to content

Commit b3f2f00

Browse files
committed
Suggest both @unsafe and @safe Fix-Its for unsafe types in signature
1 parent 4395537 commit b3f2f00

File tree

9 files changed

+68
-24
lines changed

9 files changed

+68
-24
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8126,9 +8126,13 @@ NOTE(note_use_of_unsafe_conformance_is_unsafe,none,
81268126
(Type, const ValueDecl *))
81278127

81288128
GROUPED_WARNING(decl_signature_involves_unsafe,Unsafe,none,
8129-
"%kindbase0 has an interface that is not memory-safe; "
8130-
"use '@unsafe' to indicate that its use is unsafe",
8129+
"%kindbase0 has an interface that involves unsafe types",
81318130
(const Decl *))
8131+
NOTE(decl_signature_mark_unsafe,none,
8132+
"add '@unsafe' to indicate that this declaration is unsafe to use",
8133+
())
8134+
NOTE(decl_signature_mark_safe,none,
8135+
"add '@safe' to indicate that this declaration is memory-safe to use", ())
81328136

81338137
GROUPED_WARNING(conformance_involves_unsafe,Unsafe,none,
81348138
"conformance of %0 to %kind1 involves unsafe code; use '@unsafe' to "

include/swift/Sema/ConstraintSystem.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#include "swift/AST/ASTVisitor.h"
2424
#include "swift/AST/ASTWalker.h"
2525
#include "swift/AST/AnyFunctionRef.h"
26-
#include "swift/AST/DiagnosticsSema.h"
2726
#include "swift/AST/NameLookup.h"
2827
#include "swift/AST/PropertyWrappers.h"
2928
#include "swift/AST/Types.h"

lib/Sema/TypeCheckAccess.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,9 +2696,16 @@ void swift::checkAccessControl(Decl *D) {
26962696

26972697
// If there were any unsafe uses, this declaration needs "@unsafe".
26982698
if (!unsafeUsesVec.empty()) {
2699-
D->diagnose(diag::decl_signature_involves_unsafe, D)
2700-
.fixItInsert(D->getAttributeInsertionLoc(/*forModifier=*/false),
2701-
"@unsafe ");
2699+
D->diagnose(diag::decl_signature_involves_unsafe, D);
2700+
2701+
ASTContext &ctx = D->getASTContext();
2702+
auto insertLoc = D->getAttributeInsertionLoc(/*forModifier=*/false);
2703+
2704+
ctx.Diags.diagnose(insertLoc, diag::decl_signature_mark_unsafe)
2705+
.fixItInsert(insertLoc, "@unsafe ");
2706+
ctx.Diags.diagnose(insertLoc, diag::decl_signature_mark_safe)
2707+
.fixItInsert(insertLoc, "@safe ");
2708+
27022709
std::for_each(unsafeUsesVec.begin(), unsafeUsesVec.end(),
27032710
diagnoseUnsafeUse);
27042711
}

test/Interop/Cxx/class/safe-interop-mode.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,22 @@ import Test
7171
import CoreFoundation
7272
import CxxStdlib
7373

74-
// expected-warning@+1{{global function 'useUnsafeParam' has an interface that is not memory-safe}}{{1-1=@unsafe }}
74+
// expected-warning@+3{{global function 'useUnsafeParam' has an interface that involves unsafe types}}
75+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
76+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{{1-1=@safe }}
7577
func useUnsafeParam(x: Unannotated) { // expected-note{{reference to unsafe struct 'Unannotated'}}
7678
}
7779

78-
// expected-warning@+2{{global function 'useUnsafeParam2' has an interface that is not memory-safe}}{{11:1-1=@unsafe }}
80+
// expected-warning@+4{{global function 'useUnsafeParam2' has an interface that involves unsafe types}}
81+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
82+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{{1-1=@safe }}
7983
@available(SwiftStdlib 5.8, *)
8084
func useUnsafeParam2(x: UnsafeReference) { // expected-note{{reference to unsafe class 'UnsafeReference'}}
8185
}
8286

83-
// expected-warning@+1{{global function 'useUnsafeParam3' has an interface that is not memory-safe}}{{1-1=@unsafe }}
87+
// expected-warning@+3{{global function 'useUnsafeParam3' has an interface that involves unsafe types}}
88+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
89+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{{1-1=@safe }}
8490
func useUnsafeParam3(x: UnknownEscapabilityAggregate) { // expected-note{{reference to unsafe struct 'UnknownEscapabilityAggregate'}}
8591
}
8692

@@ -95,7 +101,9 @@ func useCfType(x: CFArray) {
95101
func useString(x: std.string) {
96102
}
97103

98-
// expected-warning@+1{{global function 'useVecOfPtr' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}
104+
// expected-warning@+3{{global function 'useVecOfPtr' has an interface}}
105+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
106+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
99107
func useVecOfPtr(x: VecOfPtr) { // expected-note{{reference to unsafe type alias 'VecOfPtr'}}
100108
}
101109

@@ -105,15 +113,21 @@ func useVecOfInt(x: VecOfInt) {
105113
func useSafeTuple(x: SafeTuple) {
106114
}
107115

108-
// expected-warning@+1{{global function 'useUnsafeTuple' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}
116+
// expected-warning@+3{{global function 'useUnsafeTuple' has an interface that involves unsafe types}}
117+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
118+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
109119
func useUnsafeTuple(x: UnsafeTuple) { // expected-note{{reference to unsafe type alias 'UnsafeTuple'}}
110120
}
111121

112-
// expected-warning@+1{{global function 'useCppSpan' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}
122+
// expected-warning@+3{{global function 'useCppSpan' has an interface that involves unsafe types}}
123+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
124+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
113125
func useCppSpan(x: SpanOfInt) { // expected-note{{reference to unsafe type alias 'SpanOfInt'}}
114126
}
115127

116-
// expected-warning@+1{{global function 'useCppSpan2' has an interface that is not memory-safe}}
128+
// expected-warning@+3{{global function 'useCppSpan2' has an interface that involves unsafe types}}
129+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
130+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
117131
func useCppSpan2(x: SpanOfIntAlias) { // expected-note{{reference to unsafe type alias 'SpanOfIntAlias'}}
118132
}
119133

test/Unsafe/safe.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ func g() {
1717
unsafe unsafeFunction()
1818
}
1919

20-
// expected-warning@+1{{global function 'h' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}
20+
// expected-warning@+3{{global function 'h' has an interface that involves unsafe types}}
21+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
22+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{{1-1=@safe }}
2123
func h(_: UnsafeType) { // expected-note{{reference to unsafe struct 'UnsafeType'}}
2224
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}
2325
unsafeFunction() // expected-note{{reference to unsafe global function 'unsafeFunction()'}}
@@ -29,11 +31,15 @@ func h(_: UnsafeType) { // expected-note{{reference to unsafe struct 'UnsafeType
2931
unsafe g()
3032
}
3133

32-
// expected-warning@+1 {{global function 'rethrowing' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}{{1-1=@unsafe }}
34+
// expected-warning@+3 {{global function 'rethrowing' has an interface that involves unsafe types}}
35+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
36+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
3337
func rethrowing(body: (UnsafeType) throws -> Void) rethrows { } // expected-note{{reference to unsafe struct 'UnsafeType'}}
3438

3539
class HasStatics {
36-
// expected-warning@+1{{static method 'f' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe }}{{3-3=@unsafe }}
40+
// expected-warning@+3{{static method 'f' has an interface that involves unsafe types}}
41+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{3-3=@unsafe }}
42+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{3-3=@safe }}
3743
static internal func f(_: UnsafeType) { } // expected-note{{reference to unsafe struct 'UnsafeType'}}
3844

3945

test/Unsafe/unsafe-suppression.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ func iAmUnsafe() { }
99
@unsafe
1010
struct UnsafeType { }
1111

12-
// expected-note@+1{{reference to unsafe struct 'UnsafeType'}}
12+
// expected-note@+3{{reference to unsafe struct 'UnsafeType'}}
13+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
14+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
1315
func iAmImpliedUnsafe() -> UnsafeType? { nil }
14-
// expected-warning@-1{{global function 'iAmImpliedUnsafe' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}{{1-1=@unsafe }}
16+
// expected-warning@-1{{global function 'iAmImpliedUnsafe' has an interface that involves unsafe types}}
1517

1618
@unsafe
1719
func labeledUnsafe(_: UnsafeType) {

test/Unsafe/unsafe.swift

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,9 @@ class UnsafeSub: UnsafeSuper { }
130130
@unsafe var unsafeVar: Int = 0
131131

132132

133-
// expected-warning@+1{{global function 'testMe' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}{{1-1=@unsafe }}
133+
// expected-warning@+3{{global function 'testMe' has an interface that involves unsafe types}}
134+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
135+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
134136
func testMe(
135137
_ pointer: PointerType, // expected-note{{reference to unsafe struct 'PointerType'}}
136138
_ unsafeSuper: UnsafeSuper // expected-note{{reference to unsafe class 'UnsafeSuper'}}
@@ -151,14 +153,18 @@ func testMe(
151153
// Various declaration kinds
152154
// -----------------------------------------------------------------------
153155

154-
// expected-warning@+1{{type alias 'SuperUnsafe' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}
156+
// expected-warning@+3{{type alias 'SuperUnsafe' has an interface that involves unsafe types}}
157+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
158+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
155159
typealias SuperUnsafe = UnsafeSuper // expected-note{{reference to unsafe class 'UnsafeSuper'}}
156160

157161
@unsafe typealias SuperUnsafe2 = UnsafeSuper
158162

159163
enum HasUnsafeThings {
160164

161-
// expected-warning@+1{{enum case 'one' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe }}{{1-1=@unsafe }}
165+
// expected-warning@+3{{enum case 'one' has an interface that involves unsafe types}}
166+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
167+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
162168
case one(UnsafeSuper) // expected-note{{reference to unsafe class 'UnsafeSuper'}}
163169

164170
@unsafe case two(UnsafeSuper)

test/Unsafe/unsafe_imports.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import unsafe_decls
1010
import unsafe_swift_decls
1111

12-
// expected-warning@+1{{global function 'testUnsafe' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}{{1-1=@unsafe }}
12+
// expected-warning@+3{{global function 'testUnsafe' has an interface that involves unsafe types}}
13+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
14+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
1315
func testUnsafe(_ ut: UnsafeType) { // expected-note{{reference to unsafe struct 'UnsafeType'}}
1416
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}{{3-3=unsafe }}
1517
unsafe_c_function() // expected-note{{reference to unsafe global function 'unsafe_c_function()'}}
@@ -23,7 +25,9 @@ func testUnsafe(_ ut: UnsafeType) { // expected-note{{reference to unsafe struct
2325
// Reference a typealias that isn't itself @unsafe, but refers to an unsafe
2426
// type.
2527

26-
// expected-warning@+1{{global function 'testUnsafeThroughAlias' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}
28+
// expected-warning@+3{{global function 'testUnsafeThroughAlias' has an interface that involves unsafe types}}
29+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
30+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
2731
func testUnsafeThroughAlias(_ ut: UnsafeTypeAlias) { // expected-note{{reference to type alias 'UnsafeTypeAlias' involves unsafe type 'UnsafeTypeAlias' (aka 'PointerType')}}
2832
// TODO: Diagnostic above could be better
2933
}

test/Unsafe/unsafe_stdlib.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
// REQUIRES: swift_feature_AllowUnsafeAttribute
77
// REQUIRES: swift_feature_WarnUnsafe
88

9-
// expected-warning@+1{{global function 'test' has an interface that is not memory-safe; use '@unsafe' to indicate that its use is unsafe}}{{1-1=@unsafe }}
9+
// expected-warning@+3{{global function 'test' has an interface that involves unsafe types}}
10+
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
11+
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
1012
func test(
1113
x: OpaquePointer, // expected-note{{reference to unsafe struct 'OpaquePointer'}}
1214
other: UnsafeMutablePointer<Int> // expected-note{{reference to unsafe generic struct 'UnsafeMutablePointer'}}

0 commit comments

Comments
 (0)