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 { diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index faf2b18a10785..4cbc1ac271736 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -5985,31 +5985,6 @@ 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(); - - // 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(); - } - } - - Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any) - .highlight(inverse->getConstraint()->getSourceRange()) - .fixItInsert(anyLoc, "any "); - return Action::SkipNode(); - } - reprStack.push_back(T); auto *declRefTR = dyn_cast(T); @@ -6062,9 +6037,12 @@ 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::ImplicitlyUnwrappedOptional: case TypeReprKind::Protocol: return true; case TypeReprKind::Metatype: @@ -6079,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: @@ -6102,26 +6079,44 @@ 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 = existentialNeedsParens(*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 = existentialNeedsParens(*(parentIt - 1)); + auto it = reprStack.end() - 1; + auto replacementIt = it; + + // Backtrack the stack and expand the replacement range to any parent + // 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) || + 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; @@ -6129,13 +6124,49 @@ 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 + /// 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; + } + + 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 { @@ -6145,13 +6176,32 @@ 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); + inverse && isAnyOrSomeMissing()) { + auto diag = Ctx.Diags.diagnose(inverse->getTildeLoc(), + diag::inverse_requires_any); + emitInsertAnyFixit(diag, T); + return; + } + } + auto *decl = T->getBoundDecl(); if (!decl) { return; } 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(), @@ -6181,7 +6231,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/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/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 92ac3cbdcbbd1..86f0e7bcf3241 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,214 @@ 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-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-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 = nil + let _: Optional + // 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-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-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-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-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-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-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}} + 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-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 = ConformingType.self + let _: (HasAssoc).Type + // 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 = ConformingType.self + let _: ((HasAssoc)).Type + // 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 + // 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 + // 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)}} 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-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-20=any ~Copyable}} + 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'}}{{10-23=(any HasAssoc.Type)}} + let _: HasAssoc.Type.Protocol + // expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}} + let _: ~Copyable.Type.Protocol + // 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 + // 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? + // 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).Protocol = (any HasAssoc).self + 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? = ConformingType() + 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? = ConformingType.self + let _: HasAssoc.Type? + // 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? = (any HasAssoc).self + let _: HasAssoc.Protocol? + // 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-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-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 + // 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}} + 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-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) + // 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-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 + // 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? + let _: any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type // OK + + // Misplaced '?'. // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc)?'}}{{10-23=(any HasAssoc)?}} - let _: any HasAssoc? = nil + 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? = nil - - do { - struct Outer { - struct Inner {} - } - - // expected-error@+2:18 {{must be written 'any HasAssoc'}} - // expected-error@+1:34 {{must be written 'any HasAssoc'}} - let _: Outer.Inner - } + 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..6f0538c6c8b0b 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 { @@ -91,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 {} } } @@ -311,61 +314,214 @@ 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-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-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 = nil + let _: Optional + // 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-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-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-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-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-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-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}} + 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-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 = ConformingType.self + let _: (HasAssoc).Type + // 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 = ConformingType.self + let _: ((HasAssoc)).Type + // 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 + // 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 + // 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)}} 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-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-20=any ~Copyable}} + 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'}}{{10-23=(any HasAssoc.Type)}} + let _: HasAssoc.Type.Protocol + // expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}} + let _: ~Copyable.Type.Protocol + // 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 + // 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? + // 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).Protocol = (any HasAssoc).self + 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? = ConformingType() + 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? = ConformingType.self + let _: HasAssoc.Type? + // 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? = (any HasAssoc).self + let _: HasAssoc.Protocol? + // 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-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-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 + // 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}} + 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-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) + // 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-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 + // 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? + let _: any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type // OK + + // Misplaced '?'. // expected-error@+1 {{optional 'any' type must be written '(any HasAssoc)?'}}{{10-23=(any HasAssoc)?}} - let _: any HasAssoc? = nil + 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? = nil - - do { - struct Outer { - struct Inner {} - } - - // expected-error@+2:18 {{must be written 'any HasAssoc'}} - // expected-error@+1:34 {{must be written 'any HasAssoc'}} - let _: Outer.Inner - } + let _: any HasAssoc.Type? + // FIXME: Better recovery + // expected-error@+1 {{type '(any Copyable.Type)?' cannot be suppressed}} + let _: any ~Copyable.Type? } func testNestedMetatype() {