Skip to content

Commit 2de9f4a

Browse files
committed
[Strict safety] Stop complaining about unsafe signatures
Since we infer unsafety from a use of a declaration that involves unsafe types in its signature, there isn't a reason to require @unsafe on declaration to restate it. This matches recent revisions of SE-0458.
1 parent ae3e580 commit 2de9f4a

11 files changed

+27
-90
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8150,15 +8150,6 @@ NOTE(note_use_of_unsafe_conformance_is_unsafe,none,
81508150
"@unsafe conformance of %0 to %kind1 involves unsafe code",
81518151
(Type, const ValueDecl *))
81528152

8153-
GROUPED_WARNING(decl_signature_involves_unsafe,Unsafe,none,
8154-
"%kindbase0 has an interface that involves unsafe types",
8155-
(const Decl *))
8156-
NOTE(decl_signature_mark_unsafe,none,
8157-
"add '@unsafe' to indicate that this declaration is unsafe to use",
8158-
())
8159-
NOTE(decl_signature_mark_safe,none,
8160-
"add '@safe' to indicate that this declaration is memory-safe to use", ())
8161-
81628153
GROUPED_WARNING(conformance_involves_unsafe,Unsafe,none,
81638154
"conformance of %0 to %kind1 involves unsafe code; use '@unsafe' to "
81648155
"indicate that the conformance is not memory-safe",

lib/Sema/TypeCheckAccess.cpp

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,7 @@ class AccessControlChecker : public AccessControlCheckerBase,
13321332
if (macroDecl) {
13331333
diagnoseDeclAvailability(
13341334
macroDecl, customAttr->getTypeRepr()->getSourceRange(), nullptr,
1335-
ExportContext::forDeclSignature(const_cast<Decl *>(D), nullptr),
1335+
ExportContext::forDeclSignature(const_cast<Decl *>(D)),
13361336
std::nullopt);
13371337
}
13381338
}
@@ -2678,35 +2678,9 @@ void swift::checkAccessControl(Decl *D) {
26782678
if (isa<AccessorDecl>(D))
26792679
return;
26802680

2681-
// If we need to gather all unsafe uses from the declaration signature,
2682-
// do so now.
2683-
llvm::SmallVector<UnsafeUse, 2> unsafeUsesVec;
2684-
llvm::SmallVectorImpl<UnsafeUse> *unsafeUses = nullptr;
2685-
if (D->getASTContext().LangOpts.hasFeature(Feature::WarnUnsafe) &&
2686-
!D->isImplicit() &&
2687-
D->getExplicitSafety() == ExplicitSafety::Unspecified) {
2688-
unsafeUses = &unsafeUsesVec;
2689-
}
2690-
2691-
auto where = ExportContext::forDeclSignature(D, unsafeUses);
2681+
auto where = ExportContext::forDeclSignature(D);
26922682
if (where.isImplicit())
26932683
return;
26942684

26952685
DeclAvailabilityChecker(where).visit(D);
2696-
2697-
// If there were any unsafe uses, this declaration needs "@unsafe".
2698-
if (!unsafeUsesVec.empty()) {
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-
2709-
std::for_each(unsafeUsesVec.begin(), unsafeUsesVec.end(),
2710-
diagnoseUnsafeUse);
2711-
}
27122686
}

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3313,7 +3313,7 @@ SynthesizeMainFunctionRequest::evaluate(Evaluator &evaluator,
33133313
return nullptr;
33143314
}
33153315

3316-
auto where = ExportContext::forDeclSignature(D, nullptr);
3316+
auto where = ExportContext::forDeclSignature(D);
33173317
diagnoseDeclAvailability(mainFunction, attr->getRange(), nullptr, where,
33183318
std::nullopt);
33193319

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,7 @@ static void computeExportContextBits(ASTContext &Ctx, Decl *D, bool *spi,
246246
}
247247
}
248248

249-
ExportContext ExportContext::forDeclSignature(
250-
Decl *D, llvm::SmallVectorImpl<UnsafeUse> *unsafeUses) {
249+
ExportContext ExportContext::forDeclSignature(Decl *D) {
251250
auto &Ctx = D->getASTContext();
252251

253252
auto *DC = D->getInnermostDeclContext();
@@ -263,7 +262,7 @@ ExportContext ExportContext::forDeclSignature(
263262

264263
bool exported = ::isExported(D);
265264

266-
return ExportContext(DC, availabilityContext, fragileKind, unsafeUses,
265+
return ExportContext(DC, availabilityContext, fragileKind, nullptr,
267266
spi, exported, implicit);
268267
}
269268

@@ -286,8 +285,7 @@ ExportContext ExportContext::forFunctionBody(DeclContext *DC, SourceLoc loc) {
286285
ExportContext ExportContext::forConformance(DeclContext *DC,
287286
ProtocolDecl *proto) {
288287
assert(isa<ExtensionDecl>(DC) || isa<NominalTypeDecl>(DC));
289-
auto where = forDeclSignature(DC->getInnermostDeclarationDeclContext(),
290-
nullptr);
288+
auto where = forDeclSignature(DC->getInnermostDeclarationDeclContext());
291289

292290
where.Exported &= proto->getFormalAccessScope(
293291
DC, /*usableFromInlineAsPublic*/true).isPublic();
@@ -2947,7 +2945,7 @@ void swift::diagnoseOverrideOfUnavailableDecl(ValueDecl *override,
29472945

29482946
// FIXME: [availability] Take an unsatisfied constraint as input instead of
29492947
// recomputing it.
2950-
ExportContext where = ExportContext::forDeclSignature(override, nullptr);
2948+
ExportContext where = ExportContext::forDeclSignature(override);
29512949
auto constraint =
29522950
getUnsatisfiedAvailabilityConstraint(base, where.getAvailability());
29532951
if (!constraint)

lib/Sema/TypeCheckAvailability.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ class ExportContext {
127127
///
128128
/// If the declaration is exported, the resulting context is restricted to
129129
/// referencing exported types only. Otherwise it can reference anything.
130-
static ExportContext forDeclSignature(
131-
Decl *D, llvm::SmallVectorImpl<UnsafeUse> *unsafeUses);
130+
static ExportContext forDeclSignature(Decl *D);
132131

133132
/// Create an instance describing the declarations that can be referenced
134133
/// from the given function's body.

lib/Sema/TypeCheckStorage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ static Expr *buildStorageReference(AccessorDecl *accessor,
12361236
diagnoseDeclAvailability(
12371237
wrappedValue,
12381238
var->getAttachedPropertyWrappers()[i]->getRangeWithAt(), nullptr,
1239-
ExportContext::forDeclSignature(accessor, nullptr));
1239+
ExportContext::forDeclSignature(accessor));
12401240
}
12411241

12421242
underlyingVars.push_back({ wrappedValue, isWrapperRefLValue });

test/Unsafe/safe.swift

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

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 }}
23-
func h(_: UnsafeType) { // expected-note{{reference to unsafe struct 'UnsafeType'}}
20+
func h(_: UnsafeType) {
2421
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}
2522
unsafeFunction() // expected-note{{reference to unsafe global function 'unsafeFunction()'}}
2623

@@ -31,16 +28,10 @@ func h(_: UnsafeType) { // expected-note{{reference to unsafe struct 'UnsafeType
3128
unsafe g()
3229
}
3330

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 }}
37-
func rethrowing(body: (UnsafeType) throws -> Void) rethrows { } // expected-note{{reference to unsafe struct 'UnsafeType'}}
31+
func rethrowing(body: (UnsafeType) throws -> Void) rethrows { }
3832

3933
class HasStatics {
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 }}
43-
static internal func f(_: UnsafeType) { } // expected-note{{reference to unsafe struct 'UnsafeType'}}
34+
static internal func f(_: UnsafeType) { }
4435

4536

4637
}

test/Unsafe/unsafe-suppression.swift

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

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 }}
1512
func iAmImpliedUnsafe() -> UnsafeType? { nil }
16-
// expected-warning@-1{{global function 'iAmImpliedUnsafe' has an interface that involves unsafe types}}
1713

1814
@unsafe
1915
func labeledUnsafe(_: UnsafeType) {

test/Unsafe/unsafe.swift

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,9 @@ func testRHS(b: Bool, x: Int) {
150150
@unsafe var unsafeVar: Int = 0
151151

152152

153-
// expected-warning@+3{{global function 'testMe' has an interface that involves unsafe types}}
154-
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
155-
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
156153
func testMe(
157-
_ pointer: PointerType, // expected-note{{reference to unsafe struct 'PointerType'}}
158-
_ unsafeSuper: UnsafeSuper // expected-note{{reference to unsafe class 'UnsafeSuper'}}
154+
_ pointer: PointerType,
155+
_ unsafeSuper: UnsafeSuper
159156
) {
160157
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}{{3-3=unsafe }}
161158
unsafeF() // expected-note{{reference to unsafe global function 'unsafeF()'}}
@@ -173,19 +170,13 @@ func testMe(
173170
// Various declaration kinds
174171
// -----------------------------------------------------------------------
175172

176-
// expected-warning@+3{{type alias 'SuperUnsafe' has an interface that involves unsafe types}}
177-
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
178-
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
179-
typealias SuperUnsafe = UnsafeSuper // expected-note{{reference to unsafe class 'UnsafeSuper'}}
173+
typealias SuperUnsafe = UnsafeSuper
180174

181175
@unsafe typealias SuperUnsafe2 = UnsafeSuper
182176

183177
enum HasUnsafeThings {
184178

185-
// expected-warning@+3{{enum case 'one' has an interface that involves unsafe types}}
186-
// expected-note@+2{{add '@unsafe' to indicate that this declaration is unsafe to use}}{{1-1=@unsafe }}
187-
// expected-note@+1{{add '@safe' to indicate that this declaration is memory-safe to use}}{1-1=@safe }}
188-
case one(UnsafeSuper) // expected-note{{reference to unsafe class 'UnsafeSuper'}}
179+
case one(UnsafeSuper)
189180

190181
@unsafe case two(UnsafeSuper)
191182
}

test/Unsafe/unsafe_imports.swift

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

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 }}
15-
func testUnsafe(_ ut: UnsafeType) { // expected-note{{reference to unsafe struct 'UnsafeType'}}
12+
func testUnsafe(_ ut: UnsafeType) {
1613
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}{{3-3=unsafe }}
1714
unsafe_c_function() // expected-note{{reference to unsafe global function 'unsafe_c_function()'}}
1815

@@ -25,11 +22,14 @@ func testUnsafe(_ ut: UnsafeType) { // expected-note{{reference to unsafe struct
2522
// Reference a typealias that isn't itself @unsafe, but refers to an unsafe
2623
// type.
2724

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 }}
31-
func testUnsafeThroughAlias(_ ut: UnsafeTypeAlias) { // expected-note{{reference to type alias 'UnsafeTypeAlias' involves unsafe type 'UnsafeTypeAlias' (aka 'PointerType')}}
32-
// TODO: Diagnostic above could be better
25+
func testUnsafeThroughAlias(_ ut: UnsafeTypeAlias) {
26+
27+
}
28+
29+
func callThroughAlias(ut: UnsafeTypeAlias) {
30+
// expected-warning@+1{{expression uses unsafe constructs but is not marked with 'unsafe'}}
31+
testUnsafeThroughAlias(ut) // expected-note{{reference to global function 'testUnsafeThroughAlias' involves unsafe type 'UnsafeTypeAlias' (aka 'PointerType')}}
32+
// expected-note@-1{{reference to parameter 'ut' involves unsafe type 'UnsafeTypeAlias' (aka 'PointerType')}}
3333
}
3434

3535

test/Unsafe/unsafe_stdlib.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@
66
// REQUIRES: swift_feature_AllowUnsafeAttribute
77
// REQUIRES: swift_feature_WarnUnsafe
88

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 }}
129
func test(
13-
x: OpaquePointer, // expected-note{{reference to unsafe struct 'OpaquePointer'}}
14-
other: UnsafeMutablePointer<Int> // expected-note{{reference to unsafe generic struct 'UnsafeMutablePointer'}}
10+
x: OpaquePointer,
11+
other: UnsafeMutablePointer<Int>
1512
) {
1613
var array = [1, 2, 3]
1714
// expected-warning@+2{{expression uses unsafe constructs but is not marked with 'unsafe'}}{{3-3=unsafe }}

0 commit comments

Comments
 (0)