Skip to content

Commit 20021cf

Browse files
authored
Merge pull request #71928 from kavon/ncgenerics-fixes-1
NCGenerics: fix ExistentialAny handling
2 parents 081e527 + 18f0066 commit 20021cf

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6079,12 +6079,23 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
60796079
// If this is a type alias to a constraint type, the type
60806080
// alias name must be prefixed with 'any' to be used as an
60816081
// existential type.
6082-
if (type->isConstraintType()) {
6082+
if (type->isConstraintType() && !type->isAny() && !type->isAnyObject()) {
6083+
bool diagnose = false;
6084+
6085+
// Look for protocol members that require 'any'.
60836086
auto layout = type->getExistentialLayout();
60846087
for (auto *protoDecl : layout.getProtocols()) {
6085-
if (!protoDecl->existentialRequiresAny())
6086-
continue;
6088+
if (protoDecl->existentialRequiresAny()) {
6089+
diagnose = true;
6090+
break;
6091+
}
6092+
}
6093+
6094+
// If inverses are present, require 'any' too.
6095+
if (auto *PCT = type->getAs<ProtocolCompositionType>())
6096+
diagnose |= !PCT->getInverses().empty();
60876097

6098+
if (diagnose) {
60886099
auto diag = Ctx.Diags.diagnose(
60896100
T->getNameLoc(), diag::existential_requires_any,
60906101
alias->getDeclaredInterfaceType(),

test/Generics/inverse_generics.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,14 @@ func checkExistentials() {
466466
let _: any Escapable & ~Escapable = 1 // expected-error {{composition cannot contain '~Escapable' when another member requires 'Escapable'}}
467467
}
468468

469+
typealias NotCopyable = ~Copyable
470+
typealias EmptyComposition = ~Copyable & ~Escapable
471+
func test(_ t: borrowing NotCopyable) {} // expected-error {{use of 'NotCopyable' (aka '~Copyable') as a type must be written 'any NotCopyable'}}
472+
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')}}
473+
474+
typealias Copy = Copyable
475+
func test(_ z1: Copy, _ z2: Copyable) {}
476+
469477
// Conformances can be conditional on whether a generic parameter is Copyable
470478
protocol Arbitrary {}
471479
protocol AnotherOne {}

test/type/explicit_existential_swift6.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature ExistentialAny
2+
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature ExistentialAny -enable-experimental-feature NoncopyableGenerics
23

34
protocol HasSelfRequirements {
45
func foo(_ x: Self)
@@ -276,7 +277,7 @@ typealias Constraint = Input
276277
typealias ConstraintB = Input & InputB
277278

278279
//expected-error@+2{{use of 'Constraint' (aka 'Input') as a type must be written 'any Constraint' (aka 'any Input')}}
279-
//expected-error@+1 2{{use of 'ConstraintB' (aka 'Input & InputB') as a type must be written 'any ConstraintB' (aka 'any Input & InputB')}}
280+
//expected-error@+1 {{use of 'ConstraintB' (aka 'Input & InputB') as a type must be written 'any ConstraintB' (aka 'any Input & InputB')}}
280281
func testConstraintAlias(x: Constraint, y: ConstraintB) {}
281282

282283
typealias Existential = any Input
@@ -307,7 +308,7 @@ enum EE : Equatable, any Empty { // expected-error {{raw type 'any Empty' is not
307308
do {
308309
// expected-error@+1 {{use of protocol 'Decodable' as a type must be written 'any Decodable'}}
309310
let _: Decodable
310-
// expected-error@+1 2 {{use of 'Codable' (aka 'Decodable & Encodable') as a type must be written 'any Codable' (aka 'any Decodable & Encodable')}}
311+
// expected-error@+1 {{use of 'Codable' (aka 'Decodable & Encodable') as a type must be written 'any Codable' (aka 'any Decodable & Encodable')}}
311312
let _: Codable
312313
}
313314

@@ -395,3 +396,14 @@ protocol PP {}
395396
struct A : PP {}
396397
let _: any PP = A() // Ok
397398
let _: any (any PP) = A() // expected-error{{redundant 'any' in type 'any (any PP)'}} {{8-12=}}
399+
400+
// coverage for rdar://123332844
401+
let x: Any.Type = AnyObject.self
402+
let y: Any.Type = Any.self
403+
404+
typealias Objectlike = AnyObject
405+
func f(_ x: Objectlike) {}
406+
407+
typealias Copy = Copyable
408+
func h(_ z1: Copy, // expected-error {{use of 'Copy' (aka 'Copyable') as a type must be written 'any Copy' (aka 'any Copyable')}}
409+
_ z2: Copyable) {} // expected-error {{use of protocol 'Copyable' as a type must be written 'any Copyable'}}

0 commit comments

Comments
 (0)