Skip to content

Commit 05b529f

Browse files
committed
Sema: Accept existentials without any in swiftinterfaces.
Resolves rdar://93052306
1 parent d339d86 commit 05b529f

File tree

5 files changed

+47
-7
lines changed

5 files changed

+47
-7
lines changed

lib/Sema/MiscDiagnostics.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3541,11 +3541,12 @@ void swift::performAbstractFuncDeclDiagnostics(AbstractFunctionDecl *AFD) {
35413541
}
35423542

35433543
// Perform MiscDiagnostics on Switch Statements.
3544-
static void checkSwitch(ASTContext &ctx, const SwitchStmt *stmt) {
3544+
static void checkSwitch(ASTContext &ctx, const SwitchStmt *stmt,
3545+
DeclContext *DC) {
35453546
// We want to warn about "case .Foo, .Bar where 1 != 100:" since the where
35463547
// clause only applies to the second case, and this is surprising.
35473548
for (auto cs : stmt->getCases()) {
3548-
TypeChecker::checkExistentialTypes(ctx, cs);
3549+
TypeChecker::checkExistentialTypes(ctx, cs, DC);
35493550

35503551
// The case statement can have multiple case items, each can have a where.
35513552
// If we find a "where", and there is a preceding item without a where, and
@@ -5038,10 +5039,10 @@ void swift::performSyntacticExprDiagnostics(const Expr *E,
50385039
void swift::performStmtDiagnostics(const Stmt *S, DeclContext *DC) {
50395040
auto &ctx = DC->getASTContext();
50405041

5041-
TypeChecker::checkExistentialTypes(ctx, const_cast<Stmt *>(S));
5042-
5042+
TypeChecker::checkExistentialTypes(ctx, const_cast<Stmt *>(S), DC);
5043+
50435044
if (auto switchStmt = dyn_cast<SwitchStmt>(S))
5044-
checkSwitch(ctx, switchStmt);
5045+
checkSwitch(ctx, switchStmt, DC);
50455046

50465047
checkStmtConditionTrailingClosure(ctx, S);
50475048

lib/Sema/TypeCheckType.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4371,6 +4371,11 @@ void TypeChecker::checkExistentialTypes(Decl *decl) {
43714371
if (!decl || decl->isInvalid())
43724372
return;
43734373

4374+
// Skip diagnosing existential `any` requirements in swiftinterfaces.
4375+
auto sourceFile = decl->getDeclContext()->getParentSourceFile();
4376+
if (sourceFile && sourceFile->Kind == SourceFileKind::Interface)
4377+
return;
4378+
43744379
auto &ctx = decl->getASTContext();
43754380
if (auto *protocolDecl = dyn_cast<ProtocolDecl>(decl)) {
43764381
checkExistentialTypes(ctx, protocolDecl->getTrailingWhereClause());
@@ -4401,10 +4406,16 @@ void TypeChecker::checkExistentialTypes(Decl *decl) {
44014406
decl->walk(visitor);
44024407
}
44034408

4404-
void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt) {
4409+
void TypeChecker::checkExistentialTypes(ASTContext &ctx, Stmt *stmt,
4410+
DeclContext *DC) {
44054411
if (!stmt)
44064412
return;
44074413

4414+
// Skip diagnosing existential `any` requirements in swiftinterfaces.
4415+
auto sourceFile = DC->getParentSourceFile();
4416+
if (sourceFile && sourceFile->Kind == SourceFileKind::Interface)
4417+
return;
4418+
44084419
ExistentialTypeVisitor visitor(ctx, /*checkStatements=*/true);
44094420
stmt->walk(visitor);
44104421
}

lib/Sema/TypeChecker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *Context,
295295
void checkExistentialTypes(Decl *decl);
296296

297297
/// Check for invalid existential types in the given statement.
298-
void checkExistentialTypes(ASTContext &ctx, Stmt *stmt);
298+
void checkExistentialTypes(ASTContext &ctx, Stmt *stmt, DeclContext *DC);
299299

300300
/// Check for invalid existential types in the underlying type of
301301
/// the given type alias.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// swift-interface-format-version: 1.0
2+
// swift-compiler-version: Swift version 5.7-dev (LLVM cd62c186b914a47, Swift d74d00ef63ab637)
3+
// swift-module-flags: -swift-version 5 -enable-library-evolution -module-name ExistentialAnyMissing
4+
import Swift
5+
public protocol P {
6+
}
7+
public protocol Q {
8+
associatedtype A : ExistentialAnyMissing.P
9+
}
10+
public func takesAndReturnsP(_ x: ExistentialAnyMissing.P) -> ExistentialAnyMissing.P
11+
public func takesAndReturnsOptionalP(_ x: ExistentialAnyMissing.P?) -> ExistentialAnyMissing.P?
12+
public func takesAndReturnsQ(_ x: ExistentialAnyMissing.Q) -> ExistentialAnyMissing.Q
13+
public struct S {
14+
public var p: ExistentialAnyMissing.P
15+
public var maybeP: ExistentialAnyMissing.P?
16+
public var q: ExistentialAnyMissing.Q
17+
public var maybeQ: ExistentialAnyMissing.Q?
18+
}
19+
@inlinable internal func inlinableTakesAny(_ a: Any) {
20+
switch a {
21+
case is P: break
22+
case is Q: break
23+
default: break
24+
}
25+
}

test/ModuleInterface/existential-any.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// RUN: %target-swift-frontend -typecheck-module-from-interface %t.swiftinterface -module-name main
33
// RUN: %FileCheck %s < %t.swiftinterface
44

5+
// Verify that `any` is not required in swiftinterfaces.
6+
// RUN: %target-swift-frontend -typecheck-module-from-interface %S/Inputs/existential-any-ignore-missing-in-interface.swiftinterface -module-name ExistentialAnyMissing
7+
58
// CHECK: public protocol P
69
public protocol P { }
710

0 commit comments

Comments
 (0)