From 945dd4e5c365188d86d5af09c2d616c29dc1ab8d Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Sun, 21 Apr 2024 20:20:13 +0300 Subject: [PATCH 1/9] [NFC] AST: Define `TypeRepr::isParenType()` --- include/swift/AST/TypeRepr.h | 4 ++++ lib/AST/TypeRepr.cpp | 16 ++++++++++------ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/include/swift/AST/TypeRepr.h b/include/swift/AST/TypeRepr.h index 24d2285fd0358..214745bb0b259 100644 --- a/include/swift/AST/TypeRepr.h +++ b/include/swift/AST/TypeRepr.h @@ -184,6 +184,10 @@ class alignas(1 << TypeReprAlignInBits) TypeRepr /// opaque return type reprs. bool hasOpaque(); + /// Returns a Boolean value indicating whether this written type is + /// parenthesized, that is, matches the following grammar: `'(' type ')'`. + bool isParenType() const; + /// Retrieve the type repr without any parentheses around it. /// /// The use of this function must be restricted to contexts where diff --git a/lib/AST/TypeRepr.cpp b/lib/AST/TypeRepr.cpp index ce7b5d915c9da..2398bec807a05 100644 --- a/lib/AST/TypeRepr.cpp +++ b/lib/AST/TypeRepr.cpp @@ -109,14 +109,18 @@ bool TypeRepr::hasOpaque() { findIf([](TypeRepr *ty) { return isa(ty); }); } +bool TypeRepr::isParenType() const { + auto *tuple = dyn_cast(this); + return tuple && tuple->isParenType(); +} + TypeRepr *TypeRepr::getWithoutParens() const { - auto *repr = const_cast(this); - while (auto *tupleRepr = dyn_cast(repr)) { - if (!tupleRepr->isParenType()) - break; - repr = tupleRepr->getElementType(0); + auto *result = this; + while (result->isParenType()) { + result = cast(result)->getElementType(0); } - return repr; + + return const_cast(result); } bool TypeRepr::isSimpleUnqualifiedIdentifier(Identifier identifier) const { From f5d6159993edb3bf5b93328a9d4b4bbe833bf470 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Mon, 22 Apr 2024 23:03:20 +0300 Subject: [PATCH 2/9] [NFC] ExistentialTypeSyntaxChecker: Document, rename and make `existentialNeedsParens` static --- lib/Sema/TypeCheckType.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index faf2b18a10785..02ed3ce0c2b01 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -6062,7 +6062,9 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { } private: - bool existentialNeedsParens(TypeRepr *parent) const { + /// Returns a Boolean value indicating whether the insertion of `any` before + /// a type representation with the given parent requires paretheses. + static bool anySyntaxNeedsParens(TypeRepr *parent) { switch (parent->getKind()) { case TypeReprKind::Optional: case TypeReprKind::Protocol: @@ -6108,7 +6110,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { bool needsParens = (exprCount != 0); if (reprStack.size() > 1) { auto parentIt = reprStack.end() - 2; - needsParens = existentialNeedsParens(*parentIt); + needsParens = anySyntaxNeedsParens(*parentIt); // Expand to include parenthesis before checking if the parent needs // to be replaced. @@ -6120,7 +6122,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { if ((*parentIt)->getKind() == TypeReprKind::Metatype) { replaceRepr = *parentIt; if (parentIt != reprStack.begin()) - needsParens = existentialNeedsParens(*(parentIt - 1)); + needsParens = anySyntaxNeedsParens(*(parentIt - 1)); } } From 4e9ecc120544b31fcb70a6dd85f56d808be30c69 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Wed, 24 Apr 2024 02:33:25 +0300 Subject: [PATCH 3/9] [NFC] Reorganize and extend `any` syntax enforcement tests --- test/Parse/inverses.swift | 5 - test/type/explicit_existential.swift | 197 ++++++++++++++++---- test/type/explicit_existential_swift6.swift | 195 +++++++++++++++---- 3 files changed, 323 insertions(+), 74 deletions(-) diff --git a/test/Parse/inverses.swift b/test/Parse/inverses.swift index bdd26e64bbfdf..587badfe3cbb0 100644 --- a/test/Parse/inverses.swift +++ b/test/Parse/inverses.swift @@ -92,8 +92,6 @@ func what(one: ~Copyable..., // expected-error {{noncopyable type '~Copyable' ca struct A { struct B { struct C {} } } -typealias Z0 = (~Copyable).Type // expected-error{{constraint that suppresses conformance requires 'any'}}{{17-17=any }} -typealias Z1 = ~Copyable.Type // expected-error{{constraint that suppresses conformance requires 'any'}}{{16-16=any }} typealias Z2 = ~A.B.C // expected-error {{type 'A.B.C' cannot be suppressed}} typealias Z3 = ~A? // expected-error {{type 'A?' cannot be suppressed}} typealias Z4 = ~Rope // expected-error {{type 'Rope' cannot be suppressed}} @@ -120,12 +118,9 @@ func typeInExpression() { _ = X<(borrowing any ~Copyable) -> Void>() _ = ~Copyable.self // expected-error{{unary operator '~' cannot be applied to an operand of type '(any Copyable).Type'}} - _ = (~Copyable).self // expected-error{{constraint that suppresses conformance requires 'any'}}{{8-8=any }} _ = (any ~Copyable).self } -func param1(_ t: borrowing ~Copyable) {} // expected-error{{constraint that suppresses conformance requires 'any'}}{{28-28=any }} -func param2(_ t: ~Copyable.Type) {} // expected-error{{constraint that suppresses conformance requires 'any'}}{{18-18=any }} func param3(_ t: borrowing any ~Copyable) {} func param4(_ t: any ~Copyable.Type) {} diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index 92ac3cbdcbbd1..2683fea4c6eee 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -1,4 +1,4 @@ -// RUN: %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift -enable-experimental-feature NoncopyableGenerics protocol HasSelfRequirements { func foo(_ x: Self) @@ -57,6 +57,9 @@ typealias T2 = any Pub & Bar protocol HasAssoc { associatedtype Assoc func foo() + + typealias HasAssoc_Alias = HasAssoc + typealias Int_Alias = Int } do { @@ -279,61 +282,185 @@ do { let _: Codable } -func testAnyFixIt() { - struct ConformingType : HasAssoc { - typealias Assoc = Int - func foo() {} +protocol HasAssocGeneric { + associatedtype Assoc +} - func method() -> any HasAssoc {} +protocol NonCopyableHasAssoc: ~Copyable { + associatedtype Assoc +} + +func testAnyFixIt() { + struct S { + typealias HasAssoc_Alias = HasAssoc + typealias HasAssocGeneric_Alias = HasAssocGeneric + typealias Copyable_Alias = Copyable + + typealias G = Self + typealias NonCopyable_G = Self + typealias S = Self } + typealias G = S + typealias NonCopyable_G = S // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=any HasAssoc}} - let _: HasAssoc = ConformingType() + let _: HasAssoc + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~Copyable + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} + let _: (HasAssoc) + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~(Copyable) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{19-27=any HasAssoc}} - let _: Optional = nil + let _: Optional + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-19=any }} + let _: Optional<~Copyable> + // FIXME: No fix-it + generic argument not diagnosed. + // expected-error@+1 {{use of protocol 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric'}}{{none}} + let _: HasAssocGeneric + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{14-22=any HasAssoc}} + let _: S.G + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-26=any }} + let _: S.NonCopyable_G<~Copyable> + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + let _: G.S + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + let _: NonCopyable_G<~Copyable>.S + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} + let _: G.G + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable> + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} + let _: G.G.S + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable>.S + // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-26=any S.HasAssoc_Alias}} + let _: S.HasAssoc_Alias + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~S.Copyable_Alias + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G.HasAssoc_Alias}} + let _: G.HasAssoc_Alias + // FIXME: Generic argument not diagnosed. + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~G.Copyable_Alias + // FIXME: No fix-it + generic argument not diagnosed. + // expected-error@+1 {{use of 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric}}{{none}} + let _: S.HasAssocGeneric_Alias + // FIXME: No diagnostic. + let _: HasAssoc.Int_Alias + let _: HasAssoc.HasAssoc_Alias.Int_Alias // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} - let _: HasAssoc.Type = ConformingType.self + let _: HasAssoc.Type + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~Copyable.Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}} - let _: (HasAssoc).Type = ConformingType.self + let _: (HasAssoc).Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-27=any ((HasAssoc)).Type}} - let _: ((HasAssoc)).Type = ConformingType.self + let _: ((HasAssoc)).Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }} + let _: ((~Copyable)).Type + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + let _: HasAssoc.Type.Type + // expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}} + let _: ~Copyable.Type.Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type.Type // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}} let _: HasAssoc.Protocol = HasAssoc.self + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{33-41=any HasAssoc}} + let _: (HasAssoc).Protocol = (HasAssoc).self + // expected-error@+1 {{type '(any Copyable).Type' cannot be suppressed}} + let _: ~Copyable.Protocol + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-34=any }} + let _: (~Copyable).Protocol = (~Copyable).self + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} + let _: HasAssoc.Protocol.Type.Type + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Protocol.Type.Type do { - struct Wrapper { - typealias HasAssocAlias = HasAssoc - } - let wrapperMeta: Wrapper.Type + let meta: S.Type // FIXME: What is the correct fix-it for the initializer? // - // expected-error@+2:20 {{use of 'Wrapper.HasAssocAlias' (aka 'HasAssoc') as a type must be written 'any Wrapper.HasAssocAlias' (aka 'any HasAssoc')}}{{12-33=(any Wrapper.HasAssocAlias)}} - // expected-error@+1:57 {{use of 'Wrapper.HasAssocAlias' (aka 'HasAssoc') as a type must be written 'any Wrapper.HasAssocAlias' (aka 'any HasAssoc')}}{{57-70=(any HasAssocAlias)}} - let _: Wrapper.HasAssocAlias.Protocol = wrapperMeta.HasAssocAlias.self + // expected-error@+2:14 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{12-28=(any S.HasAssoc_Alias)}} + // expected-error@+1:45 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{45-59=(any HasAssoc_Alias)}} + let _: S.HasAssoc_Alias.Protocol = meta.HasAssoc_Alias.self } - // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} - let _: (HasAssoc).Protocol = (any HasAssoc).self + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} + let _: HasAssoc.Type.Protocol + // expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}} + let _: ~Copyable.Type.Protocol + // FIXME: Incorrect fix-it. + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type.Protocol + // FIXME: Incorrect fix-it. + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + let _: HasAssoc.Type.Type.Protocol + // FIXME: Incorrect fix-it. + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type.Type.Protocol // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} - let _: HasAssoc? = ConformingType() + let _: HasAssoc? + // expected-error@+1 {{type '(any Copyable)?' cannot be suppressed}} + let _: ~Copyable? + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} + let _: (HasAssoc)? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable)? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} - let _: HasAssoc.Type? = ConformingType.self + let _: HasAssoc.Type? + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} - let _: HasAssoc.Protocol? = (any HasAssoc).self + let _: HasAssoc.Protocol? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Protocol? + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{21-29=any HasAssoc}} + let _: (borrowing HasAssoc) -> Void + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + let _: (borrowing ~Copyable) -> Void + // https://github.com/apple/swift/issues/72588 + // FIXME: No diagnostic. + let _: any HasAssocGeneric + let _: any HasAssocGeneric<~Copyable> + let _: any G.HasAssoc_Alias + let _: any ~G.Copyable_Alias + do { + func f(_: some G.HasAssoc_Alias) {} + } - // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc)?'}}{{10-23=(any HasAssoc)?}} - let _: any HasAssoc? = nil - // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc.Type)?'}}{{10-28=(any HasAssoc.Type)?}} - let _: any HasAssoc.Type? = nil + // Misc. compound cases. - do { - struct Outer { - struct Inner {} - } + // FIXME: Incorrect fix-it for 'NonCopyableHasAssoc'. + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-40=any NonCopyableHasAssoc}} + let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void - // expected-error@+2:18 {{must be written 'any HasAssoc'}} - // expected-error@+1:34 {{must be written 'any HasAssoc'}} - let _: Outer.Inner - } + // Misplaced '?'. + + // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc)?'}}{{10-23=(any HasAssoc)?}} + let _: any HasAssoc? + // FIXME: Better recovery + // expected-error@+1 {{type '(any Copyable)?' cannot be suppressed}} + let _: any ~Copyable? + // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc.Type)?'}}{{10-28=(any HasAssoc.Type)?}} + let _: any HasAssoc.Type? + // FIXME: Better recovery + // expected-error@+1 {{type '(any Copyable.Type)?' cannot be suppressed}} + let _: any ~Copyable.Type? } func testNestedMetatype() { diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index 5114dde067bab..7073207136b91 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -62,6 +62,9 @@ typealias T2 = any Pub & Bar protocol HasAssoc { associatedtype Assoc func foo() + + typealias HasAssoc_Alias = HasAssoc + typealias Int_Alias = Int } do { @@ -311,61 +314,185 @@ do { let _: Codable } -func testAnyFixIt() { - struct ConformingType : HasAssoc { - typealias Assoc = Int - func foo() {} +protocol HasAssocGeneric { + associatedtype Assoc +} - func method() -> any HasAssoc {} +protocol NonCopyableHasAssoc: ~Copyable { + associatedtype Assoc +} + +func testAnyFixIt() { + struct S { + typealias HasAssoc_Alias = HasAssoc + typealias HasAssocGeneric_Alias = HasAssocGeneric + typealias Copyable_Alias = Copyable + + typealias G = Self + typealias NonCopyable_G = Self + typealias S = Self } + typealias G = S + typealias NonCopyable_G = S // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=any HasAssoc}} - let _: HasAssoc = ConformingType() + let _: HasAssoc + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~Copyable + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} + let _: (HasAssoc) + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~(Copyable) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{19-27=any HasAssoc}} - let _: Optional = nil + let _: Optional + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-19=any }} + let _: Optional<~Copyable> + // FIXME: No fix-it + generic argument not diagnosed. + // expected-error@+1 {{use of protocol 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric'}}{{none}} + let _: HasAssocGeneric + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{14-22=any HasAssoc}} + let _: S.G + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-26=any }} + let _: S.NonCopyable_G<~Copyable> + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + let _: G.S + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + let _: NonCopyable_G<~Copyable>.S + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} + let _: G.G + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable> + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} + let _: G.G.S + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable>.S + // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-26=any S.HasAssoc_Alias}} + let _: S.HasAssoc_Alias + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~S.Copyable_Alias + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} + // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G.HasAssoc_Alias}} + let _: G.HasAssoc_Alias + // FIXME: Generic argument not diagnosed. + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~G.Copyable_Alias + // FIXME: No fix-it + generic argument not diagnosed. + // expected-error@+1 {{use of 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric}}{{none}} + let _: S.HasAssocGeneric_Alias + // FIXME: No diagnostic. + let _: HasAssoc.Int_Alias + let _: HasAssoc.HasAssoc_Alias.Int_Alias // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} - let _: HasAssoc.Type = ConformingType.self + let _: HasAssoc.Type + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~Copyable.Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}} - let _: (HasAssoc).Type = ConformingType.self + let _: (HasAssoc).Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-27=any ((HasAssoc)).Type}} - let _: ((HasAssoc)).Type = ConformingType.self + let _: ((HasAssoc)).Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }} + let _: ((~Copyable)).Type + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + let _: HasAssoc.Type.Type + // expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}} + let _: ~Copyable.Type.Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type.Type // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}} let _: HasAssoc.Protocol = HasAssoc.self + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{33-41=any HasAssoc}} + let _: (HasAssoc).Protocol = (HasAssoc).self + // expected-error@+1 {{type '(any Copyable).Type' cannot be suppressed}} + let _: ~Copyable.Protocol + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-34=any }} + let _: (~Copyable).Protocol = (~Copyable).self + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} + let _: HasAssoc.Protocol.Type.Type + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Protocol.Type.Type do { - struct Wrapper { - typealias HasAssocAlias = HasAssoc - } - let wrapperMeta: Wrapper.Type + let meta: S.Type // FIXME: What is the correct fix-it for the initializer? // - // expected-error@+2:20 {{use of 'Wrapper.HasAssocAlias' (aka 'HasAssoc') as a type must be written 'any Wrapper.HasAssocAlias' (aka 'any HasAssoc')}}{{12-33=(any Wrapper.HasAssocAlias)}} - // expected-error@+1:57 {{use of 'Wrapper.HasAssocAlias' (aka 'HasAssoc') as a type must be written 'any Wrapper.HasAssocAlias' (aka 'any HasAssoc')}}{{57-70=(any HasAssocAlias)}} - let _: Wrapper.HasAssocAlias.Protocol = wrapperMeta.HasAssocAlias.self + // expected-error@+2:14 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{12-28=(any S.HasAssoc_Alias)}} + // expected-error@+1:45 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{45-59=(any HasAssoc_Alias)}} + let _: S.HasAssoc_Alias.Protocol = meta.HasAssoc_Alias.self } - // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} - let _: (HasAssoc).Protocol = (any HasAssoc).self + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} + let _: HasAssoc.Type.Protocol + // expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}} + let _: ~Copyable.Type.Protocol + // FIXME: Incorrect fix-it. + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type.Protocol + // FIXME: Incorrect fix-it. + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + let _: HasAssoc.Type.Type.Protocol + // FIXME: Incorrect fix-it. + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type.Type.Protocol // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} - let _: HasAssoc? = ConformingType() + let _: HasAssoc? + // expected-error@+1 {{type '(any Copyable)?' cannot be suppressed}} + let _: ~Copyable? + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} + let _: (HasAssoc)? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable)? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} - let _: HasAssoc.Type? = ConformingType.self + let _: HasAssoc.Type? + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Type? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} - let _: HasAssoc.Protocol? = (any HasAssoc).self + let _: HasAssoc.Protocol? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable).Protocol? + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{21-29=any HasAssoc}} + let _: (borrowing HasAssoc) -> Void + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + let _: (borrowing ~Copyable) -> Void + // https://github.com/apple/swift/issues/72588 + // FIXME: No diagnostic. + let _: any HasAssocGeneric + let _: any HasAssocGeneric<~Copyable> + let _: any G.HasAssoc_Alias + let _: any ~G.Copyable_Alias + do { + func f(_: some G.HasAssoc_Alias) {} + } - // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc)?'}}{{10-23=(any HasAssoc)?}} - let _: any HasAssoc? = nil - // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc.Type)?'}}{{10-28=(any HasAssoc.Type)?}} - let _: any HasAssoc.Type? = nil + // Misc. compound cases. - do { - struct Outer { - struct Inner {} - } + // FIXME: Incorrect fix-it for 'NonCopyableHasAssoc'. + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-40=any NonCopyableHasAssoc}} + let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void - // expected-error@+2:18 {{must be written 'any HasAssoc'}} - // expected-error@+1:34 {{must be written 'any HasAssoc'}} - let _: Outer.Inner - } + // Misplaced '?'. + + // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc)?'}}{{10-23=(any HasAssoc)?}} + let _: any HasAssoc? + // FIXME: Better recovery + // expected-error@+1 {{type '(any Copyable)?' cannot be suppressed}} + let _: any ~Copyable? + // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc.Type)?'}}{{10-28=(any HasAssoc.Type)?}} + let _: any HasAssoc.Type? + // FIXME: Better recovery + // expected-error@+1 {{type '(any Copyable.Type)?' cannot be suppressed}} + let _: any ~Copyable.Type? } func testNestedMetatype() { From 403878c86356a3209106660a5367b3e7b9e10078 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Wed, 27 Mar 2024 17:03:30 +0300 Subject: [PATCH 4/9] ExistentialTypeSyntaxChecker: Look through `any` and `some` --- lib/Sema/TypeCheckType.cpp | 73 ++++++++++++++------- test/decl/protocol/protocols.swift | 6 +- test/type/explicit_existential.swift | 7 +- test/type/explicit_existential_swift6.swift | 9 ++- 4 files changed, 67 insertions(+), 28 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 02ed3ce0c2b01..0da862a8583b5 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -5985,33 +5985,28 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { if (T->isInvalid()) return Action::SkipNode(); - // Arbitrary protocol constraints are OK on opaque types. - if (isa(T)) - return Action::SkipNode(); - - // Arbitrary protocol constraints are okay for 'any' types. - if (isa(T)) - return Action::SkipNode(); + reprStack.push_back(T); // Suppressed conformance needs to be within any/some. if (auto inverse = dyn_cast(T)) { - // Find an enclosing protocol composition, if there is one, so we - // can insert 'any' before that. - SourceLoc anyLoc = inverse->getTildeLoc(); - if (!reprStack.empty()) { - if (isa(reprStack.back())) { - anyLoc = reprStack.back()->getStartLoc(); + if (isAnyOrSomeMissing()) { + // Find an enclosing protocol composition, if there is one, so we + // can insert 'any' before that. + SourceLoc anyLoc = inverse->getTildeLoc(); + if (reprStack.size() > 1) { + if (auto *repr = + dyn_cast(*(reprStack.end() - 2))) { + anyLoc = repr->getStartLoc(); + } } - } - Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any) - .highlight(inverse->getConstraint()->getSourceRange()) - .fixItInsert(anyLoc, "any "); - return Action::SkipNode(); + Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any) + .highlight(inverse->getConstraint()->getSourceRange()) + .fixItInsert(anyLoc, "any "); + } + return Action::SkipChildren(); } - reprStack.push_back(T); - auto *declRefTR = dyn_cast(T); if (!declRefTR) { return Action::Continue(); @@ -6140,6 +6135,40 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { diag.fixItReplace(replaceRepr->getSourceRange(), fix); } + /// Returns a Boolean value indicating whether the type representation being + /// visited, assuming it is a constraint type demanding `any` or `some`, is + /// missing either keyword. + bool isAnyOrSomeMissing() const { + if (reprStack.size() < 2) { + return true; + } + + auto it = reprStack.end() - 1; + while (true) { + --it; + if (it == reprStack.begin()) { + break; + } + + // Look through parens, inverses, metatypes, and compositions. + if ((*it)->isParenType() || isa(*it) || + isa(*it) || isa(*it)) { + continue; + } + + // Look through '?' and '!' too; `any P?` et al. is diagnosed in the + // type resolver. + if (isa(*it) || + isa(*it)) { + continue; + } + + break; + } + + return !(isa(*it) || isa(*it)); + } + void checkDeclRefTypeRepr(DeclRefTypeRepr *T) const { assert(!T->isInvalid()); @@ -6153,7 +6182,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { } if (auto *proto = dyn_cast(decl)) { - if (proto->existentialRequiresAny()) { + if (proto->existentialRequiresAny() && isAnyOrSomeMissing()) { auto diag = Ctx.Diags.diagnose(T->getNameLoc(), diag::existential_requires_any, proto->getDeclaredInterfaceType(), @@ -6183,7 +6212,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { if (auto *PCT = type->getAs()) diagnose |= !PCT->getInverses().empty(); - if (diagnose) { + if (diagnose && isAnyOrSomeMissing()) { auto diag = Ctx.Diags.diagnose( T->getNameLoc(), diag::existential_requires_any, alias->getDeclaredInterfaceType(), diff --git a/test/decl/protocol/protocols.swift b/test/decl/protocol/protocols.swift index 7458f99c2a421..b89db8820f24b 100644 --- a/test/decl/protocol/protocols.swift +++ b/test/decl/protocol/protocols.swift @@ -103,9 +103,9 @@ struct DoesNotConform : Up { // Circular protocols protocol CircleMiddle : CircleStart { func circle_middle() } -// expected-note@-1 2 {{protocol 'CircleMiddle' declared here}} -protocol CircleStart : CircleEnd { func circle_start() } // expected-error 2 {{protocol 'CircleStart' refines itself}} -protocol CircleEnd : CircleMiddle { func circle_end()} // expected-note 2 {{protocol 'CircleEnd' declared here}} +// expected-note@-1 3 {{protocol 'CircleMiddle' declared here}} +protocol CircleStart : CircleEnd { func circle_start() } // expected-error 3 {{protocol 'CircleStart' refines itself}} +protocol CircleEnd : CircleMiddle { func circle_end()} // expected-note 3 {{protocol 'CircleEnd' declared here}} protocol CircleEntry : CircleTrivial { } protocol CircleTrivial : CircleTrivial { } // expected-error {{protocol 'CircleTrivial' refines itself}} diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index 2683fea4c6eee..2a6b401e07727 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -433,12 +433,16 @@ func testAnyFixIt() { // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} let _: (borrowing ~Copyable) -> Void // https://github.com/apple/swift/issues/72588 - // FIXME: No diagnostic. + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=any HasAssoc}} let _: any HasAssocGeneric + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-30=any }} let _: any HasAssocGeneric<~Copyable> + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}} let _: any G.HasAssoc_Alias + // FIXME: Generic argument not diagnosed. let _: any ~G.Copyable_Alias do { + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{22-30=any HasAssoc}} func f(_: some G.HasAssoc_Alias) {} } @@ -448,6 +452,7 @@ func testAnyFixIt() { // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-40=any NonCopyableHasAssoc}} let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void + let _: any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type // OK // Misplaced '?'. diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index 7073207136b91..16f5de5e4ff0a 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -94,7 +94,7 @@ func testHasAssoc(_ x: Any, _: any HasAssoc) { func method() -> any HasAssoc {} func existentialArray() -> [any HasAssoc] {} - func existentialcSequence() -> any Sequence {} + func existentialcSequence() -> any Sequence {} } } @@ -465,12 +465,16 @@ func testAnyFixIt() { // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} let _: (borrowing ~Copyable) -> Void // https://github.com/apple/swift/issues/72588 - // FIXME: No diagnostic. + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=any HasAssoc}} let _: any HasAssocGeneric + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-30=any }} let _: any HasAssocGeneric<~Copyable> + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}} let _: any G.HasAssoc_Alias + // FIXME: Generic argument not diagnosed. let _: any ~G.Copyable_Alias do { + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{22-30=any HasAssoc}} func f(_: some G.HasAssoc_Alias) {} } @@ -480,6 +484,7 @@ func testAnyFixIt() { // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-40=any NonCopyableHasAssoc}} let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void + let _: any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type // OK // Misplaced '?'. From f28cfe40593575d837bcb913aa3ab99b0f48dd83 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Thu, 25 Apr 2024 03:48:18 +0300 Subject: [PATCH 5/9] ExistentialTypeSyntaxChecker: Look through inverses --- lib/Sema/TypeCheckType.cpp | 52 +++++++++++++-------- test/type/explicit_existential.swift | 4 +- test/type/explicit_existential_swift6.swift | 4 +- 3 files changed, 36 insertions(+), 24 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 0da862a8583b5..171773b1a6d94 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -5987,26 +5987,6 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { reprStack.push_back(T); - // Suppressed conformance needs to be within any/some. - if (auto inverse = dyn_cast(T)) { - if (isAnyOrSomeMissing()) { - // Find an enclosing protocol composition, if there is one, so we - // can insert 'any' before that. - SourceLoc anyLoc = inverse->getTildeLoc(); - if (reprStack.size() > 1) { - if (auto *repr = - dyn_cast(*(reprStack.end() - 2))) { - anyLoc = repr->getStartLoc(); - } - } - - Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any) - .highlight(inverse->getConstraint()->getSourceRange()) - .fixItInsert(anyLoc, "any "); - } - return Action::SkipChildren(); - } - auto *declRefTR = dyn_cast(T); if (!declRefTR) { return Action::Continue(); @@ -6139,6 +6119,8 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { /// visited, assuming it is a constraint type demanding `any` or `some`, is /// missing either keyword. bool isAnyOrSomeMissing() const { + assert(isa(reprStack.back())); + if (reprStack.size() < 2) { return true; } @@ -6176,6 +6158,36 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { return; } + // Backtrack the stack, looking just through parentheses and metatypes. If + // we find an inverse (which always requires `any`), diagnose it specially. + if (reprStack.size() > 1) { + auto it = reprStack.end() - 2; + while (it != reprStack.begin() && + ((*it)->isParenType() || isa(*it))) { + --it; + continue; + } + + if (auto inverse = dyn_cast(*it)) { + if (isAnyOrSomeMissing()) { + // Find an enclosing protocol composition, if there is one, so we + // can insert 'any' before that. + SourceLoc anyLoc = inverse->getTildeLoc(); + if (it != reprStack.begin()) { + if (auto *comp = dyn_cast(*(it - 1))) { + anyLoc = comp->getStartLoc(); + } + } + + Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any) + .highlight(inverse->getConstraint()->getSourceRange()) + .fixItInsert(anyLoc, "any "); + + return; + } + } + } + auto *decl = T->getBoundDecl(); if (!decl) { return; diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index 2a6b401e07727..669ef1e921094 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -345,7 +345,7 @@ func testAnyFixIt() { // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G.HasAssoc_Alias}} let _: G.HasAssoc_Alias - // FIXME: Generic argument not diagnosed. + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{13-21=any HasAssoc}} // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} let _: ~G.Copyable_Alias // FIXME: No fix-it + generic argument not diagnosed. @@ -439,7 +439,7 @@ func testAnyFixIt() { let _: any HasAssocGeneric<~Copyable> // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}} let _: any G.HasAssoc_Alias - // FIXME: Generic argument not diagnosed. + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{17-25=any HasAssoc}} let _: any ~G.Copyable_Alias do { // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{22-30=any HasAssoc}} diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index 16f5de5e4ff0a..c9ac850b480df 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -377,7 +377,7 @@ func testAnyFixIt() { // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G.HasAssoc_Alias}} let _: G.HasAssoc_Alias - // FIXME: Generic argument not diagnosed. + // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{13-21=any HasAssoc}} // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} let _: ~G.Copyable_Alias // FIXME: No fix-it + generic argument not diagnosed. @@ -471,7 +471,7 @@ func testAnyFixIt() { let _: any HasAssocGeneric<~Copyable> // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}} let _: any G.HasAssoc_Alias - // FIXME: Generic argument not diagnosed. + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{17-25=any HasAssoc}} let _: any ~G.Copyable_Alias do { // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{22-30=any HasAssoc}} From 4a3747f92f59fe89fd398db3a3a913552536cad8 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Thu, 25 Apr 2024 04:15:40 +0300 Subject: [PATCH 6/9] ExistentialTypeSyntaxChecker: Fix `any` fix-it for higher-order metatypes --- lib/Sema/TypeCheckType.cpp | 47 +++++++++++++-------- test/type/explicit_existential.swift | 12 ++++-- test/type/explicit_existential_swift6.swift | 12 ++++-- 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 171773b1a6d94..bdc486b83fe0c 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -6079,26 +6079,39 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { } void emitInsertAnyFixit(InFlightDiagnostic &diag, DeclRefTypeRepr *T) const { - TypeRepr *replaceRepr = T; + TypeRepr *replacementT = T; // Insert parens in expression context for '(any P).self' bool needsParens = (exprCount != 0); + + // Compute the replacement node (the node to which to apply `any`). if (reprStack.size() > 1) { - auto parentIt = reprStack.end() - 2; - needsParens = anySyntaxNeedsParens(*parentIt); - - // Expand to include parenthesis before checking if the parent needs - // to be replaced. - while (parentIt != reprStack.begin() && - (*parentIt)->getWithoutParens() != *parentIt) - parentIt -= 1; - - // For existential metatypes, 'any' is applied to the metatype. - if ((*parentIt)->getKind() == TypeReprKind::Metatype) { - replaceRepr = *parentIt; - if (parentIt != reprStack.begin()) - needsParens = anySyntaxNeedsParens(*(parentIt - 1)); + auto it = reprStack.end() - 1; + auto replacementIt = it; + + // Backtrack the stack and expand the replacement range to any parent + // `.Type` metatypes, skipping only parentheses. + do { + --it; + if ((*it)->isParenType()) { + continue; + } + + if (isa(*it)) { + replacementIt = it; + continue; + } + + break; + } while (it != reprStack.begin()); + + // Whether parentheses are necessary is determined by the immediate parent + // of the replacement node. + if (replacementIt != reprStack.begin()) { + needsParens = anySyntaxNeedsParens(*(replacementIt - 1)); } + + replacementT = *replacementIt; } llvm::SmallString<64> fix; @@ -6106,13 +6119,13 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { llvm::raw_svector_ostream OS(fix); if (needsParens) OS << "("; - ExistentialTypeRepr existential(SourceLoc(), replaceRepr); + ExistentialTypeRepr existential(SourceLoc(), replacementT); existential.print(OS); if (needsParens) OS << ")"; } - diag.fixItReplace(replaceRepr->getSourceRange(), fix); + diag.fixItReplace(replacementT->getSourceRange(), fix); } /// Returns a Boolean value indicating whether the type representation being diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index 669ef1e921094..e6b3b98a940c8 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -358,6 +358,8 @@ func testAnyFixIt() { let _: HasAssoc.Type // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} let _: ~Copyable.Type + // expected-error@+1 {{type 'any Copyable.Type' cannot be suppressed}} + let _: ~(Copyable.Type) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}} let _: (HasAssoc).Type // FIXME: Fix-it produces singleton, not existential, metatype type? @@ -368,13 +370,18 @@ func testAnyFixIt() { // FIXME: Fix-it produces singleton, not existential, metatype type? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }} let _: ((~Copyable)).Type - // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=any HasAssoc.Type.Type}} let _: HasAssoc.Type.Type // expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}} let _: ~Copyable.Type.Type // FIXME: Fix-it produces singleton, not existential, metatype type? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} let _: (~Copyable).Type.Type + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-30=any (HasAssoc.Type).Type}} + let _: (HasAssoc.Type).Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable.Type).Type // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}} let _: HasAssoc.Protocol = HasAssoc.self @@ -405,8 +412,7 @@ func testAnyFixIt() { // FIXME: Incorrect fix-it. // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} let _: (~Copyable).Type.Protocol - // FIXME: Incorrect fix-it. - // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=(any HasAssoc.Type.Type)}} let _: HasAssoc.Type.Type.Protocol // FIXME: Incorrect fix-it. // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index c9ac850b480df..3a9d3e7f9e20e 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -390,6 +390,8 @@ func testAnyFixIt() { let _: HasAssoc.Type // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} let _: ~Copyable.Type + // expected-error@+1 {{type 'any Copyable.Type' cannot be suppressed}} + let _: ~(Copyable.Type) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}} let _: (HasAssoc).Type // FIXME: Fix-it produces singleton, not existential, metatype type? @@ -400,13 +402,18 @@ func testAnyFixIt() { // FIXME: Fix-it produces singleton, not existential, metatype type? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }} let _: ((~Copyable)).Type - // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=any HasAssoc.Type.Type}} let _: HasAssoc.Type.Type // expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}} let _: ~Copyable.Type.Type // FIXME: Fix-it produces singleton, not existential, metatype type? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} let _: (~Copyable).Type.Type + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-30=any (HasAssoc.Type).Type}} + let _: (HasAssoc.Type).Type + // FIXME: Fix-it produces singleton, not existential, metatype type? + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + let _: (~Copyable.Type).Type // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}} let _: HasAssoc.Protocol = HasAssoc.self @@ -437,8 +444,7 @@ func testAnyFixIt() { // FIXME: Incorrect fix-it. // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} let _: (~Copyable).Type.Protocol - // FIXME: Incorrect fix-it. - // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=(any HasAssoc.Type.Type)}} let _: HasAssoc.Type.Type.Protocol // FIXME: Incorrect fix-it. // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} From 912a07afa1ff5ddaa9f0edd72214bfcd9da56df1 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Thu, 28 Mar 2024 17:53:00 +0300 Subject: [PATCH 7/9] ExistentialTypeSyntaxChecker: Fix `any` fix-it for compositions --- lib/Sema/TypeCheckType.cpp | 4 ++-- test/type/explicit_existential.swift | 24 +++++++++++++++++++-- test/type/explicit_existential_swift6.swift | 24 +++++++++++++++++++-- 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index bdc486b83fe0c..a5b6116d747d7 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -6090,14 +6090,14 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { auto replacementIt = it; // Backtrack the stack and expand the replacement range to any parent - // `.Type` metatypes, skipping only parentheses. + // compositions or `.Type` metatypes, skipping only parentheses. do { --it; if ((*it)->isParenType()) { continue; } - if (isa(*it)) { + if (isa(*it) || isa(*it)) { replacementIt = it; continue; } diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index e6b3b98a940c8..b2833f2f1858c 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -451,13 +451,33 @@ func testAnyFixIt() { // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{22-30=any HasAssoc}} func f(_: some G.HasAssoc_Alias) {} } + // https://github.com/apple/swift/issues/65027 + // expected-error@+2:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} + // expected-error@+1:21 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} + let _: HasAssoc & HasAssoc + // expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~Copyable & ~Copyable + // expected-error@+3:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} + // expected-error@+2:22 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} + // expected-error@+1:33 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} + let _: HasAssoc & (HasAssoc & HasAssoc) + // FIXME: Incorrect fix-its for nested composition. + // expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} + // expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} + let _: ~Copyable & (~Copyable & ~Copyable) // Misc. compound cases. - // FIXME: Incorrect fix-it for 'NonCopyableHasAssoc'. // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} - // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-40=any NonCopyableHasAssoc}} + // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}} let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void + // FIXME: Incorrect fix-it. + // expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{15-15=any }} + // expected-error@+2:28 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} + // expected-error@+1:51 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} + let _: (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type? let _: any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type // OK // Misplaced '?'. diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index 3a9d3e7f9e20e..cd6bf0f774a30 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -483,13 +483,33 @@ func testAnyFixIt() { // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{22-30=any HasAssoc}} func f(_: some G.HasAssoc_Alias) {} } + // https://github.com/apple/swift/issues/65027 + // expected-error@+2:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} + // expected-error@+1:21 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} + let _: HasAssoc & HasAssoc + // expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + let _: ~Copyable & ~Copyable + // expected-error@+3:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} + // expected-error@+2:22 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} + // expected-error@+1:33 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} + let _: HasAssoc & (HasAssoc & HasAssoc) + // FIXME: Incorrect fix-its for nested composition. + // expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} + // expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} + let _: ~Copyable & (~Copyable & ~Copyable) // Misc. compound cases. - // FIXME: Incorrect fix-it for 'NonCopyableHasAssoc'. // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} - // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-40=any NonCopyableHasAssoc}} + // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}} let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void + // FIXME: Incorrect fix-it. + // expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{15-15=any }} + // expected-error@+2:28 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} + // expected-error@+1:51 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} + let _: (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type? let _: any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type // OK // Misplaced '?'. From 716400372fbd2492f21691a8110aaddf38cf9b4d Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Thu, 25 Apr 2024 05:07:12 +0300 Subject: [PATCH 8/9] ExistentialTypeSyntaxChecker: Fix `any` fix-it for inverse constraints --- lib/Sema/TypeCheckType.cpp | 32 ++++----- test/type/explicit_existential.swift | 75 +++++++++------------ test/type/explicit_existential_swift6.swift | 75 +++++++++------------ 3 files changed, 79 insertions(+), 103 deletions(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index a5b6116d747d7..6cdf54f549be9 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -6090,14 +6090,19 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { auto replacementIt = it; // Backtrack the stack and expand the replacement range to any parent - // compositions or `.Type` metatypes, skipping only parentheses. + // inverses, compositions or `.Type` metatypes, skipping only parentheses. + // + // E.g. `(X & ~P).Type` → `any (X & ~P).Type`. + // ↑ + // We're here do { --it; if ((*it)->isParenType()) { continue; } - if (isa(*it) || isa(*it)) { + if (isa(*it) || isa(*it) || + isa(*it)) { replacementIt = it; continue; } @@ -6181,23 +6186,12 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { continue; } - if (auto inverse = dyn_cast(*it)) { - if (isAnyOrSomeMissing()) { - // Find an enclosing protocol composition, if there is one, so we - // can insert 'any' before that. - SourceLoc anyLoc = inverse->getTildeLoc(); - if (it != reprStack.begin()) { - if (auto *comp = dyn_cast(*(it - 1))) { - anyLoc = comp->getStartLoc(); - } - } - - Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any) - .highlight(inverse->getConstraint()->getSourceRange()) - .fixItInsert(anyLoc, "any "); - - return; - } + if (auto *inverse = dyn_cast(*it); + inverse && isAnyOrSomeMissing()) { + auto diag = Ctx.Diags.diagnose(inverse->getTildeLoc(), + diag::inverse_requires_any); + emitInsertAnyFixit(diag, T); + return; } } diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index b2833f2f1858c..620224960dd24 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -305,48 +305,48 @@ func testAnyFixIt() { // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=any HasAssoc}} let _: HasAssoc - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-19=any ~Copyable}} let _: ~Copyable // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} let _: (HasAssoc) - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-21=any ~(Copyable)}} let _: ~(Copyable) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{19-27=any HasAssoc}} let _: Optional - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-19=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-28=any ~Copyable}} let _: Optional<~Copyable> // FIXME: No fix-it + generic argument not diagnosed. // expected-error@+1 {{use of protocol 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric'}}{{none}} let _: HasAssocGeneric // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{14-22=any HasAssoc}} let _: S.G - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-26=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-35=any ~Copyable}} let _: S.NonCopyable_G<~Copyable> // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} let _: G.S - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}} let _: NonCopyable_G<~Copyable>.S // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} let _: G.G - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-58=any ~Copyable}} let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable> // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} let _: G.G.S - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-58=any ~Copyable}} let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable>.S // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-26=any S.HasAssoc_Alias}} let _: S.HasAssoc_Alias - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-27=any ~S.Copyable_Alias}} let _: ~S.Copyable_Alias // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G.HasAssoc_Alias}} let _: G.HasAssoc_Alias // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{13-21=any HasAssoc}} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-37=any ~G.Copyable_Alias}} let _: ~G.Copyable_Alias // FIXME: No fix-it + generic argument not diagnosed. // expected-error@+1 {{use of 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric}}{{none}} @@ -356,31 +356,27 @@ func testAnyFixIt() { let _: HasAssoc.HasAssoc_Alias.Int_Alias // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} let _: HasAssoc.Type - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-24=any ~Copyable.Type}} let _: ~Copyable.Type // expected-error@+1 {{type 'any Copyable.Type' cannot be suppressed}} let _: ~(Copyable.Type) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}} let _: (HasAssoc).Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=any (~Copyable).Type}} let _: (~Copyable).Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-27=any ((HasAssoc)).Type}} let _: ((HasAssoc)).Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-28=any ((~Copyable)).Type}} let _: ((~Copyable)).Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=any HasAssoc.Type.Type}} let _: HasAssoc.Type.Type // expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}} let _: ~Copyable.Type.Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=any (~Copyable).Type.Type}} let _: (~Copyable).Type.Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-30=any (HasAssoc.Type).Type}} let _: (HasAssoc.Type).Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=any (~Copyable.Type).Type}} let _: (~Copyable.Type).Type // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}} @@ -390,12 +386,12 @@ func testAnyFixIt() { let _: (HasAssoc).Protocol = (HasAssoc).self // expected-error@+1 {{type '(any Copyable).Type' cannot be suppressed}} let _: ~Copyable.Protocol - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-34=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-43=any ~Copyable}} let _: (~Copyable).Protocol = (~Copyable).self // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} let _: HasAssoc.Protocol.Type.Type - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable).Protocol.Type.Type do { let meta: S.Type @@ -409,13 +405,11 @@ func testAnyFixIt() { let _: HasAssoc.Type.Protocol // expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}} let _: ~Copyable.Type.Protocol - // FIXME: Incorrect fix-it. - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}} let _: (~Copyable).Type.Protocol // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=(any HasAssoc.Type.Type)}} let _: HasAssoc.Type.Type.Protocol - // FIXME: Incorrect fix-it. - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=(any (~Copyable).Type.Type)}} let _: (~Copyable).Type.Type.Protocol // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} let _: HasAssoc? @@ -423,25 +417,24 @@ func testAnyFixIt() { let _: ~Copyable? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} let _: (HasAssoc)? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable)? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} let _: HasAssoc.Type? - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}} let _: (~Copyable).Type? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} let _: HasAssoc.Protocol? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable).Protocol? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{21-29=any HasAssoc}} let _: (borrowing HasAssoc) -> Void - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-30=any ~Copyable}} let _: (borrowing ~Copyable) -> Void // https://github.com/apple/swift/issues/72588 // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=any HasAssoc}} let _: any HasAssocGeneric - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-30=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-39=any ~Copyable}} let _: any HasAssocGeneric<~Copyable> // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}} let _: any G.HasAssoc_Alias @@ -455,26 +448,24 @@ func testAnyFixIt() { // expected-error@+2:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} // expected-error@+1:21 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} let _: HasAssoc & HasAssoc - // expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} - // expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-31=any ~Copyable & ~Copyable}} + // expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-31=any ~Copyable & ~Copyable}} let _: ~Copyable & ~Copyable // expected-error@+3:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} // expected-error@+2:22 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} // expected-error@+1:33 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} let _: HasAssoc & (HasAssoc & HasAssoc) - // FIXME: Incorrect fix-its for nested composition. - // expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} - // expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} - // expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} + // expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}} + // expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}} + // expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}} let _: ~Copyable & (~Copyable & ~Copyable) // Misc. compound cases. - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}} // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}} let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void - // FIXME: Incorrect fix-it. - // expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{15-15=any }} + // expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} // expected-error@+2:28 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} // expected-error@+1:51 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} let _: (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type? diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index cd6bf0f774a30..448740005882e 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -337,48 +337,48 @@ func testAnyFixIt() { // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=any HasAssoc}} let _: HasAssoc - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-19=any ~Copyable}} let _: ~Copyable // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} let _: (HasAssoc) - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-21=any ~(Copyable)}} let _: ~(Copyable) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{19-27=any HasAssoc}} let _: Optional - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-19=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-28=any ~Copyable}} let _: Optional<~Copyable> // FIXME: No fix-it + generic argument not diagnosed. // expected-error@+1 {{use of protocol 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric'}}{{none}} let _: HasAssocGeneric // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{14-22=any HasAssoc}} let _: S.G - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-26=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-35=any ~Copyable}} let _: S.NonCopyable_G<~Copyable> // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} let _: G.S - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}} let _: NonCopyable_G<~Copyable>.S // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} let _: G.G - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-58=any ~Copyable}} let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable> // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}} let _: G.G.S - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-58=any ~Copyable}} let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable>.S // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-26=any S.HasAssoc_Alias}} let _: S.HasAssoc_Alias - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-27=any ~S.Copyable_Alias}} let _: ~S.Copyable_Alias // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}} // expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G.HasAssoc_Alias}} let _: G.HasAssoc_Alias // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{13-21=any HasAssoc}} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-37=any ~G.Copyable_Alias}} let _: ~G.Copyable_Alias // FIXME: No fix-it + generic argument not diagnosed. // expected-error@+1 {{use of 'HasAssocGeneric' as a type must be written 'any HasAssocGeneric}}{{none}} @@ -388,31 +388,27 @@ func testAnyFixIt() { let _: HasAssoc.HasAssoc_Alias.Int_Alias // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}} let _: HasAssoc.Type - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-24=any ~Copyable.Type}} let _: ~Copyable.Type // expected-error@+1 {{type 'any Copyable.Type' cannot be suppressed}} let _: ~(Copyable.Type) // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}} let _: (HasAssoc).Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=any (~Copyable).Type}} let _: (~Copyable).Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-27=any ((HasAssoc)).Type}} let _: ((HasAssoc)).Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-28=any ((~Copyable)).Type}} let _: ((~Copyable)).Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=any HasAssoc.Type.Type}} let _: HasAssoc.Type.Type // expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}} let _: ~Copyable.Type.Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=any (~Copyable).Type.Type}} let _: (~Copyable).Type.Type // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-30=any (HasAssoc.Type).Type}} let _: (HasAssoc.Type).Type - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=any (~Copyable.Type).Type}} let _: (~Copyable.Type).Type // expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}} @@ -422,12 +418,12 @@ func testAnyFixIt() { let _: (HasAssoc).Protocol = (HasAssoc).self // expected-error@+1 {{type '(any Copyable).Type' cannot be suppressed}} let _: ~Copyable.Protocol - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-34=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-43=any ~Copyable}} let _: (~Copyable).Protocol = (~Copyable).self // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} let _: HasAssoc.Protocol.Type.Type - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable).Protocol.Type.Type do { let meta: S.Type @@ -441,13 +437,11 @@ func testAnyFixIt() { let _: HasAssoc.Type.Protocol // expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}} let _: ~Copyable.Type.Protocol - // FIXME: Incorrect fix-it. - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}} let _: (~Copyable).Type.Protocol // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=(any HasAssoc.Type.Type)}} let _: HasAssoc.Type.Type.Protocol - // FIXME: Incorrect fix-it. - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=(any (~Copyable).Type.Type)}} let _: (~Copyable).Type.Type.Protocol // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} let _: HasAssoc? @@ -455,25 +449,24 @@ func testAnyFixIt() { let _: ~Copyable? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}} let _: (HasAssoc)? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable)? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} let _: HasAssoc.Type? - // FIXME: Fix-it produces singleton, not existential, metatype type? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}} let _: (~Copyable).Type? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} let _: HasAssoc.Protocol? - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable).Protocol? // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{21-29=any HasAssoc}} let _: (borrowing HasAssoc) -> Void - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-30=any ~Copyable}} let _: (borrowing ~Copyable) -> Void // https://github.com/apple/swift/issues/72588 // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=any HasAssoc}} let _: any HasAssocGeneric - // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-30=any }} + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-39=any ~Copyable}} let _: any HasAssocGeneric<~Copyable> // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}} let _: any G.HasAssoc_Alias @@ -487,26 +480,24 @@ func testAnyFixIt() { // expected-error@+2:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} // expected-error@+1:21 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}} let _: HasAssoc & HasAssoc - // expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} - // expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} + // expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-31=any ~Copyable & ~Copyable}} + // expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-31=any ~Copyable & ~Copyable}} let _: ~Copyable & ~Copyable // expected-error@+3:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} // expected-error@+2:22 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} // expected-error@+1:33 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}} let _: HasAssoc & (HasAssoc & HasAssoc) - // FIXME: Incorrect fix-its for nested composition. - // expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }} - // expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} - // expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }} + // expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}} + // expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}} + // expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}} let _: ~Copyable & (~Copyable & ~Copyable) // Misc. compound cases. - // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }} + // expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}} // expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}} let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void - // FIXME: Incorrect fix-it. - // expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{15-15=any }} + // expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} // expected-error@+2:28 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} // expected-error@+1:51 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}} let _: (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type? From c9ecbe97925ddac60c3acdb4688751051daca91f Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Thu, 28 Mar 2024 17:59:43 +0300 Subject: [PATCH 9/9] ExistentialTypeSyntaxChecker: Fix `any` fix-it for IUO --- lib/Sema/TypeCheckType.cpp | 2 +- test/type/explicit_existential.swift | 7 +++++++ test/type/explicit_existential_swift6.swift | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 6cdf54f549be9..4cbc1ac271736 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -6042,6 +6042,7 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { static bool anySyntaxNeedsParens(TypeRepr *parent) { switch (parent->getKind()) { case TypeReprKind::Optional: + case TypeReprKind::ImplicitlyUnwrappedOptional: case TypeReprKind::Protocol: return true; case TypeReprKind::Metatype: @@ -6056,7 +6057,6 @@ class ExistentialTypeSyntaxChecker : public ASTWalker { case TypeReprKind::UnqualifiedIdent: case TypeReprKind::QualifiedIdent: case TypeReprKind::Dictionary: - case TypeReprKind::ImplicitlyUnwrappedOptional: case TypeReprKind::Inverse: case TypeReprKind::Tuple: case TypeReprKind::Fixed: diff --git a/test/type/explicit_existential.swift b/test/type/explicit_existential.swift index 620224960dd24..86f0e7bcf3241 100644 --- a/test/type/explicit_existential.swift +++ b/test/type/explicit_existential.swift @@ -419,6 +419,13 @@ func testAnyFixIt() { let _: (HasAssoc)? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable)? + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} + let _: HasAssoc! + // expected-error@+2 {{type '(any Copyable)?' cannot be suppressed}} + // expected-warning@+1 {{using '!' is not allowed here; treating this as '?' instead}} + let _: ~Copyable! + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} + let _: (~Copyable)! // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} let _: HasAssoc.Type? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}} diff --git a/test/type/explicit_existential_swift6.swift b/test/type/explicit_existential_swift6.swift index 448740005882e..6f0538c6c8b0b 100644 --- a/test/type/explicit_existential_swift6.swift +++ b/test/type/explicit_existential_swift6.swift @@ -451,6 +451,13 @@ func testAnyFixIt() { let _: (HasAssoc)? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} let _: (~Copyable)? + // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}} + let _: HasAssoc! + // expected-error@+2 {{type '(any Copyable)?' cannot be suppressed}} + // expected-warning@+1 {{using '!' is not allowed here; treating this as '?' instead}} + let _: ~Copyable! + // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}} + let _: (~Copyable)! // expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}} let _: HasAssoc.Type? // expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}}