Skip to content

Commit 466eb6d

Browse files
committed
TypeCheckType: Unconditionally warn about missing existential any until Swift 7
swiftlang#72659 turned out to have some source compatibility fallout that we need to fix. Instead of introducing yet another brittle compatibility hack, stop emitting errors about a missing `any` altogether until a future language mode. Besides resolving the compatibility issue, this will encourage developers to adopt any sooner and grant us ample time to gracefully address any remaining bugs before the source compatibility burden resurfaces. A subsequent commit adds a diagnostic group that will allow users to escalate these warnings to errors with `-Werror ExistentialAny`.
1 parent 707ea39 commit 466eb6d

12 files changed

+157
-156
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -895,11 +895,15 @@ static Type applyGenericArguments(Type type,
895895
auto parameterized =
896896
ParameterizedProtocolType::get(ctx, protoType, argTys);
897897

898+
// FIXME: Can this not be done in ExistentialTypeSyntaxChecker?
898899
if (resolution.getOptions().isConstraintImplicitExistential() &&
899900
!ctx.LangOpts.hasFeature(Feature::ImplicitSome)) {
900-
diags.diagnose(loc, diag::existential_requires_any, parameterized,
901-
ExistentialType::get(parameterized),
902-
/*isAlias=*/isa<TypeAliasType>(type.getPointer()));
901+
diags
902+
.diagnose(loc, diag::existential_requires_any, parameterized,
903+
ExistentialType::get(parameterized),
904+
/*isAlias=*/isa<TypeAliasType>(type.getPointer()))
905+
.warnUntilSwiftVersion(7);
906+
903907
return ErrorType::get(ctx);
904908
}
905909

@@ -6115,16 +6119,13 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
61156119
ASTContext &Ctx;
61166120
bool checkStatements;
61176121
bool hitTopStmt;
6118-
bool warnUntilSwift7;
61196122

61206123
unsigned exprCount = 0;
61216124
llvm::SmallVector<TypeRepr *, 4> reprStack;
61226125

61236126
public:
6124-
ExistentialTypeSyntaxChecker(ASTContext &ctx, bool checkStatements,
6125-
bool warnUntilSwift7 = false)
6126-
: Ctx(ctx), checkStatements(checkStatements), hitTopStmt(false),
6127-
warnUntilSwift7(warnUntilSwift7) {}
6127+
ExistentialTypeSyntaxChecker(ASTContext &ctx, bool checkStatements)
6128+
: Ctx(ctx), checkStatements(checkStatements), hitTopStmt(false) {}
61286129

61296130
MacroWalking getMacroWalkingBehavior() const override {
61306131
return MacroWalking::ArgumentsAndExpansion;
@@ -6338,7 +6339,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
63386339
inverse && isAnyOrSomeMissing()) {
63396340
auto diag = Ctx.Diags.diagnose(inverse->getTildeLoc(),
63406341
diag::inverse_requires_any);
6341-
diag.warnUntilSwiftVersionIf(warnUntilSwift7, 7);
6342+
diag.warnUntilSwiftVersion(7);
63426343
emitInsertAnyFixit(diag, T);
63436344
return;
63446345
}
@@ -6356,7 +6357,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
63566357
proto->getDeclaredInterfaceType(),
63576358
proto->getDeclaredExistentialType(),
63586359
/*isAlias=*/false);
6359-
diag.warnUntilSwiftVersionIf(warnUntilSwift7, 7);
6360+
diag.warnUntilSwiftVersion(7);
63606361
emitInsertAnyFixit(diag, T);
63616362
}
63626363
} else if (auto *alias = dyn_cast<TypeAliasDecl>(decl)) {
@@ -6387,7 +6388,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
63876388
alias->getDeclaredInterfaceType(),
63886389
ExistentialType::get(alias->getDeclaredInterfaceType()),
63896390
/*isAlias=*/true);
6390-
diag.warnUntilSwiftVersionIf(warnUntilSwift7, 7);
6391+
diag.warnUntilSwiftVersion(7);
63916392
emitInsertAnyFixit(diag, T);
63926393
}
63936394
}
@@ -6467,14 +6468,7 @@ void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt,
64676468
if (sourceFile && sourceFile->Kind == SourceFileKind::Interface)
64686469
return;
64696470

6470-
// Previously we missed this diagnostic on 'catch' statements, downgrade
6471-
// to a warning until Swift 7.
6472-
auto downgradeUntilSwift7 = false;
6473-
if (auto *CS = dyn_cast<CaseStmt>(stmt))
6474-
downgradeUntilSwift7 = CS->getParentKind() == CaseParentKind::DoCatch;
6475-
6476-
ExistentialTypeSyntaxChecker checker(ctx, /*checkStatements=*/true,
6477-
downgradeUntilSwift7);
6471+
ExistentialTypeSyntaxChecker checker(ctx, /*checkStatements=*/true);
64786472
stmt->walk(checker);
64796473
}
64806474

test/Generics/inverse_generics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,8 @@ func checkExistentials() {
471471

472472
typealias NotCopyable = ~Copyable
473473
typealias EmptyComposition = ~Copyable & ~Escapable
474-
func test(_ t: borrowing NotCopyable) {} // expected-error {{use of 'NotCopyable' (aka '~Copyable') as a type must be written 'any NotCopyable'}}
475-
func test(_ t: borrowing EmptyComposition) {} // expected-error {{use of 'EmptyComposition' (aka '~Copyable & ~Escapable') as a type must be written 'any EmptyComposition' (aka 'any ~Copyable & ~Escapable')}}
474+
func test(_ t: borrowing NotCopyable) {} // expected-warning {{use of 'NotCopyable' (aka '~Copyable') as a type must be written 'any NotCopyable'}}
475+
func test(_ t: borrowing EmptyComposition) {} // expected-warning {{use of 'EmptyComposition' (aka '~Copyable & ~Escapable') as a type must be written 'any EmptyComposition' (aka 'any ~Copyable & ~Escapable')}}
476476

477477
typealias Copy = Copyable
478478
func test(_ z1: Copy, _ z2: Copyable) {}

test/Macros/macros_diagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ struct MyStruct<T: MyProto> {
196196

197197
struct SomeType {
198198
#genericUnary<Equatable>(0 as Hashable)
199-
// expected-error@-1{{use of protocol 'Equatable' as a type must be written 'any Equatable'}}
200-
// expected-error@-2{{use of protocol 'Hashable' as a type must be written 'any Hashable'}}
199+
// expected-warning@-1{{use of protocol 'Equatable' as a type must be written 'any Equatable'}}
200+
// expected-warning@-2{{use of protocol 'Hashable' as a type must be written 'any Hashable'}}
201201
// expected-error@-3{{external macro implementation type}}
202202
}
203203

test/Macros/top_level_freestanding.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ func testGlobalVariable() {
107107

108108
// expected-note @+1 6 {{in expansion of macro 'anonymousTypes' here}}
109109
#anonymousTypes(causeErrors: true) { "foo" }
110-
// DIAG_BUFFERS-DAG: @__swiftmacro_9MacroUser0033top_level_freestandingswift_DbGHjfMX108_0_33_082AE7CFEFA6960C804A9FE7366EB5A0Ll14anonymousTypesfMf0_{{.*}}: error: use of protocol 'Equatable' as a type must be written 'any Equatable'
111-
// DIAG_BUFFERS-DAG: @__swiftmacro_9MacroUser00142___swiftmacro_9MacroUser0033top_level_freestandingswift_DbGHjfMX108_0_33_082AE7CFEFA6960C804A9FE7366EB5A0Ll14anonymousTypesfMf0_swift_DAIABdjIbfMX23_2_33_082AE7CFEFA6960C804A9FE7366EB5A0Ll27introduceTypeCheckingErrorsfMf_{{.*}}: error: use of protocol 'Hashable' as a type must be written 'any Hashable'
110+
// DIAG_BUFFERS-DAG: @__swiftmacro_9MacroUser0033top_level_freestandingswift_DbGHjfMX108_0_33_082AE7CFEFA6960C804A9FE7366EB5A0Ll14anonymousTypesfMf0_{{.*}}: warning: use of protocol 'Equatable' as a type must be written 'any Equatable'
111+
// DIAG_BUFFERS-DAG: @__swiftmacro_9MacroUser00142___swiftmacro_9MacroUser0033top_level_freestandingswift_DbGHjfMX108_0_33_082AE7CFEFA6960C804A9FE7366EB5A0Ll14anonymousTypesfMf0_swift_DAIABdjIbfMX23_2_33_082AE7CFEFA6960C804A9FE7366EB5A0Ll27introduceTypeCheckingErrorsfMf_{{.*}}: warning: use of protocol 'Hashable' as a type must be written 'any Hashable'
112112

113113
// expected-note @+1 2 {{in expansion of macro 'anonymousTypes' here}}
114114
#anonymousTypes { () -> String in
115-
// expected-error @+1 {{use of protocol 'Equatable' as a type must be written 'any Equatable'}}
115+
// expected-warning @+1 {{use of protocol 'Equatable' as a type must be written 'any Equatable'}}
116116
_ = 0 as Equatable
117117
return "foo"
118118
}

test/decl/nested/protocol.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ extension OuterProtocol {
237237

238238
struct ConformsToOuterProtocol : OuterProtocol {
239239
typealias Hen = Int
240-
func f() { let _ = InnerProtocol.self } // expected-error {{use of protocol 'InnerProtocol' as a type must be written 'any InnerProtocol'}}
240+
func f() { let _ = InnerProtocol.self } // expected-warning {{use of protocol 'InnerProtocol' as a type must be written 'any InnerProtocol'}}
241241
}
242242

243243
extension OuterProtocol {

test/decl/protocol/existential_member_accesses_self_assoctype_fixit.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ protocol P {
1212
protocol Q {}
1313

1414
do {
15-
func test(p: P) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
15+
func test(p: P) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
1616
p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:16--1:17=some P}} {{none}}
1717
}
1818
}
1919
do {
20-
func test(p: ((P))) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
20+
func test(p: ((P))) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
2121
p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:18--1:19=some P}} {{none}}
2222
}
2323
}
@@ -57,12 +57,12 @@ do {
5757
}
5858
}
5959
do {
60-
func test(p: P.Type) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
60+
func test(p: P.Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
6161
p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:16--1:17=(some P)}} {{none}}
6262
}
6363
}
6464
do {
65-
func test(p: (P).Type) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
65+
func test(p: (P).Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
6666
p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:17--1:18=some P}} {{none}}
6767
}
6868
}
@@ -78,12 +78,12 @@ do {
7878
}
7979

8080
do {
81-
func test(p: P & Q) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
81+
func test(p: P & Q) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
8282
p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:16--1:21=some P & Q}} {{none}}
8383
}
8484
}
8585
do {
86-
func test(p: ((P & Q))) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
86+
func test(p: ((P & Q))) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
8787
p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:18--1:23=some P & Q}} {{none}}
8888
}
8989
}
@@ -123,12 +123,12 @@ do {
123123
}
124124
}
125125
do {
126-
func test(p: (P & Q).Type) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
126+
func test(p: (P & Q).Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
127127
p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P & Q).Type'; consider using a generic constraint instead}} {{-1:17--1:22=some P & Q}} {{none}}
128128
}
129129
}
130130
do {
131-
func test(p: ((P & Q)).Type) { // expected-error {{use of protocol 'P' as a type must be written 'any P'}}
131+
func test(p: ((P & Q)).Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}}
132132
p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P & Q).Type'; consider using a generic constraint instead}} {{-1:18--1:23=some P & Q}} {{none}}
133133
}
134134
}

test/decl/protocol/protocols.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ func i<T : C3>(_ x : T?) -> Bool {
475475
// expected-warning@-1 {{checking a value with optional type 'T?' against type 'any P1' succeeds whenever the value is non-nil; did you mean to use '!= nil'?}}
476476
}
477477
func j(_ x : C1) -> Bool {
478-
return x is P1 // expected-error {{use of protocol 'P1' as a type must be written 'any P1'}}
478+
return x is P1 // expected-warning {{use of protocol 'P1' as a type must be written 'any P1'}}
479479
}
480480
func k(_ x : C1?) -> Bool {
481481
return x is any P1

test/decl/protocol/recursive_requirement.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// RUN: %target-typecheck-verify-swift
2-
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures 2>&1 | %FileCheck %s
2+
// RUN: %target-swift-frontend -typecheck %s -debug-generic-signatures 2>&1 | %FileCheck %s
33

44
// -----
55

@@ -95,7 +95,7 @@ protocol AsExistentialB {
9595
}
9696

9797
protocol AsExistentialAssocTypeA {
98-
var delegate : AsExistentialAssocTypeB? { get } // expected-error {{use of protocol 'AsExistentialAssocTypeB' as a type must be written 'any AsExistentialAssocTypeB'}}
98+
var delegate : (any AsExistentialAssocTypeB)? { get }
9999
}
100100
protocol AsExistentialAssocTypeB {
101101
func aMethod(_ object : AsExistentialAssocTypeA)
@@ -107,7 +107,7 @@ protocol AsExistentialAssocTypeAgainA {
107107
associatedtype Bar
108108
}
109109
protocol AsExistentialAssocTypeAgainB {
110-
func aMethod(_ object : AsExistentialAssocTypeAgainA) // expected-error {{use of protocol 'AsExistentialAssocTypeAgainA' as a type must be written 'any AsExistentialAssocTypeAgainA'}}
110+
func aMethod(_ object : any AsExistentialAssocTypeAgainA)
111111
}
112112

113113
// https://github.com/apple/swift/issues/43164

0 commit comments

Comments
 (0)