diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index d3b5934ecb2..f8dc3626500 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -3972,8 +3972,11 @@ bool InvalidMemberRefOnExistential::diagnoseAsError() { // If the base expression is a reference to a function or subscript // parameter, offer a fixit that replaces the existential parameter type with - // its generic equivalent, e.g. func foo(p: any P) → func foo(p: T). - // FIXME: Add an option to use 'some' vs. an explicit generic parameter. + // its generic equivalent, e.g. func foo(p: any P) → func foo(p: some P). + // Replacing 'any' with 'some' allows the code to compile without further + // changes, such as naming an explicit type parameter, and is future-proofed + // for same-type requirements on primary associated types instead of needing + // a where clause. if (!PD || !PD->getDeclContext()->getAsDecl()) return true; @@ -4022,70 +4025,42 @@ bool InvalidMemberRefOnExistential::diagnoseAsError() { if (PD->isInOut()) return true; - constexpr StringRef GPNamePlaceholder = "<#generic parameter name#>"; - SourceRange TyReplacementRange; - SourceRange RemoveAnyRange; - SourceLoc GPDeclLoc; - std::string GPDeclStr; - { - llvm::raw_string_ostream OS(GPDeclStr); - auto *const GC = PD->getDeclContext()->getAsDecl()->getAsGenericContext(); - if (GC->getParsedGenericParams()) { - GPDeclLoc = GC->getParsedGenericParams()->getRAngleLoc(); - OS << ", "; - } else { - GPDeclLoc = - isa(GC) - ? cast(GC)->getParameters()->getLParenLoc() - : cast(GC)->getIndices()->getLParenLoc(); - OS << "<"; - } - OS << GPNamePlaceholder << ": "; - - auto *TR = PD->getTypeRepr()->getWithoutParens(); - if (auto *STR = dyn_cast(TR)) { - TR = STR->getBase()->getWithoutParens(); - } - if (auto *ETR = dyn_cast(TR)) { - TR = ETR->getConstraint(); - RemoveAnyRange = SourceRange(ETR->getAnyLoc(), TR->getStartLoc()); - TR = TR->getWithoutParens(); - } - if (auto *MTR = dyn_cast(TR)) { - TR = MTR->getBase(); - - // (P & Q).Type -> T.Type - // (P).Type -> (T).Type - // ((P & Q)).Type -> ((T)).Type - if (auto *TTR = dyn_cast(TR)) { - assert(TTR->isParenType()); - if (!isa(TTR->getElementType(0))) { - TR = TR->getWithoutParens(); - } - } - } - TyReplacementRange = TR->getSourceRange(); - - // Strip any remaining parentheses and print the conformance constraint. - TR->getWithoutParens()->print(OS); - - if (!GC->getParsedGenericParams()) { - OS << ">"; - } + auto *typeRepr = PD->getTypeRepr()->getWithoutParens(); + if (auto *STR = dyn_cast(typeRepr)) { + typeRepr = STR->getBase()->getWithoutParens(); } - // First, replace the constraint type with the generic parameter type - // placeholder. - Diag.fixItReplace(TyReplacementRange, GPNamePlaceholder); + SourceRange anyRange; + TypeRepr *constraintRepr = typeRepr; + if (auto *existentialRepr = dyn_cast(typeRepr)) { + constraintRepr = existentialRepr->getConstraint()->getWithoutParens(); + auto anyStart = existentialRepr->getAnyLoc(); + auto anyEnd = existentialRepr->getConstraint()->getStartLoc(); + anyRange = SourceRange(anyStart, anyEnd); + } - // Remove 'any' if needed, using a character-based removal to pick up + bool needsParens = false; + while (auto *metatype = dyn_cast(constraintRepr)) { + // The generic equivalent of 'any P.Type' is '(some P).Type' + constraintRepr = metatype->getBase()->getWithoutParens(); + if (isa(constraintRepr)) + needsParens = !isa(metatype->getBase()); + } + + std::string fix; + llvm::raw_string_ostream OS(fix); + if (needsParens) + OS << "("; + OS << "some "; + constraintRepr->print(OS); + if (needsParens) + OS << ")"; + + // When removing 'any', use a character-based removal to pick up // whitespaces between it and its constraint repr. - if (RemoveAnyRange.isValid()) { - Diag.fixItRemoveChars(RemoveAnyRange.Start, RemoveAnyRange.End); - } - - // Finally, insert the generic parameter declaration. - Diag.fixItInsert(GPDeclLoc, GPDeclStr); + Diag + .fixItReplace(constraintRepr->getSourceRange(), fix) + .fixItRemoveChars(anyRange.Start, anyRange.End); return true; } diff --git a/test/decl/protocol/existential_member_accesses_self_assoctype_fixit.swift b/test/decl/protocol/existential_member_accesses_self_assoctype_fixit.swift index cae8780f031..89d4788375a 100644 --- a/test/decl/protocol/existential_member_accesses_self_assoctype_fixit.swift +++ b/test/decl/protocol/existential_member_accesses_self_assoctype_fixit.swift @@ -13,17 +13,17 @@ protocol Q {} do { func test(p: P) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:16--1:17=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:16--1:17=some P}} {{none}} } } do { func test(p: ((P))) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:18--1:19=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:18--1:19=some P}} {{none}} } } do { func test(p: any P) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:20--1:21=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:20--1:21=some P}} {{-1:16--1:20=}} {{none}} } } do { @@ -33,63 +33,63 @@ do { } do { func test(p: __shared (any P)) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:30--1:31=<#generic parameter name#>}} {{-1:26--1:30=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:30--1:31=some P}} {{-1:26--1:30=}} {{none}} } } do { func test(p: ((any P))) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:22--1:23=<#generic parameter name#>}} {{-1:18--1:22=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:22--1:23=some P}} {{-1:18--1:22=}} {{none}} } } do { func test(p: any (P)) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P)'; consider using a generic constraint instead}} {{-1:21--1:22=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P)'; consider using a generic constraint instead}} {{-1:21--1:22=some P}} {{-1:16--1:20=}} {{none}} } } do { func test(p: any P) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:22--1:23=<#generic parameter name#>}} {{-1:16--1:22=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:22--1:23=some P}} {{-1:16--1:22=}} {{none}} } } do { func test(p: (any (P))) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P)'; consider using a generic constraint instead}} {{-1:23--1:24=<#generic parameter name#>}} {{-1:17--1:22=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P)'; consider using a generic constraint instead}} {{-1:23--1:24=some P}} {{-1:17--1:22=}} {{none}} } } do { func test(p: P.Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:16--1:17=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:16--1:17=(some P)}} {{none}} } } do { func test(p: (P).Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P).Type'; consider using a generic constraint instead}} {{-1:17--1:18=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P).Type'; consider using a generic constraint instead}} {{-1:17--1:18=some P}} {{none}} } } do { func test(p: any P.Type) { - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:20--1:21=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:20--1:21=(some P)}} {{-1:16--1:20=}} {{none}} } } do { func test(p: any ((P).Type)) { - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P).Type'; consider using a generic constraint instead}} {{-1:22--1:23=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P).Type'; consider using a generic constraint instead}} {{-1:22--1:23=some P}} {{-1:16--1:20=}} {{none}} } } do { func test(p: P & Q) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:16--1:21=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:16--1:21=some P & Q}} {{none}} } } do { func test(p: ((P & Q))) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:18--1:23=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:18--1:23=some P & Q}} {{none}} } } do { func test(p: any P & Q) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:20--1:25=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:20--1:25=some P & Q}} {{-1:16--1:20=}} {{none}} } } do { @@ -99,100 +99,100 @@ do { } do { func test(p: __shared (any P & Q)) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:30--1:35=<#generic parameter name#>}} {{-1:26--1:30=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:30--1:35=some P & Q}} {{-1:26--1:30=}} {{none}} } } do { func test(p: ((any P & Q))) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:22--1:27=<#generic parameter name#>}} {{-1:18--1:22=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:22--1:27=some P & Q}} {{-1:18--1:22=}} {{none}} } } do { func test(p: any (P & Q)) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P & Q)'; consider using a generic constraint instead}} {{-1:21--1:26=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P & Q)'; consider using a generic constraint instead}} {{-1:21--1:26=some P & Q}} {{-1:16--1:20=}} {{none}} } } do { func test(p: any P & Q) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:22--1:27=<#generic parameter name#>}} {{-1:16--1:22=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:22--1:27=some P & Q}} {{-1:16--1:22=}} {{none}} } } do { func test(p: (any (P & Q))) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P & Q)'; consider using a generic constraint instead}} {{-1:23--1:28=<#generic parameter name#>}} {{-1:17--1:22=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any (P & Q)'; consider using a generic constraint instead}} {{-1:23--1:28=some P & Q}} {{-1:17--1:22=}} {{none}} } } do { func test(p: (P & Q).Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P & Q).Type'; consider using a generic constraint instead}} {{-1:16--1:23=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P & Q).Type'; consider using a generic constraint instead}} {{-1:17--1:22=some P & Q}} {{none}} } } do { func test(p: ((P & Q)).Type) { // expected-warning {{use of protocol 'P' as a type must be written 'any P'}} - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any ((P & Q)).Type'; consider using a generic constraint instead}} {{-1:18--1:23=<#generic parameter name#>}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any ((P & Q)).Type'; consider using a generic constraint instead}} {{-1:18--1:23=some P & Q}} {{none}} } } do { func test(p: any (P & Q).Type) { - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P & Q).Type'; consider using a generic constraint instead}} {{-1:20--1:27=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any (P & Q).Type'; consider using a generic constraint instead}} {{-1:21--1:26=some P & Q}} {{-1:16--1:20=}} {{none}} } } do { func test(p: any (((P & Q)).Type)) { - p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any ((P & Q)).Type'; consider using a generic constraint instead}} {{-1:23--1:28=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} + p.staticMethod(false) // expected-error {{member 'staticMethod' cannot be used on value of type 'any ((P & Q)).Type'; consider using a generic constraint instead}} {{-1:23--1:28=some P & Q}} {{-1:16--1:20=}} {{none}} } } do { // With an existing generic parameter list. func test(t: T, p: any P) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:39--1:40=<#generic parameter name#>}} {{-1:35--1:39=}} {{-1:24--1:24=, <#generic parameter name#>: P}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:39--1:40=some P}} {{-1:35--1:39=}} {{none}} } } do { // With an subscript expression. func test(p: any P) { - p[false] // expected-error {{member 'subscript' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:20--1:21=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p[false] // expected-error {{member 'subscript' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:20--1:21=some P}} {{-1:16--1:20=}} {{none}} } } do { // With an initializer. func test(p: any P.Type) { - p.init(false) // expected-error {{member 'init' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:20--1:21=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.init(false) // expected-error {{member 'init' cannot be used on value of type 'any P.Type'; consider using a generic constraint instead}} {{-1:20--1:21=(some P)}} {{-1:16--1:20=}} {{none}} } } // Inside initializers, accessors and subscripts. struct Test { init(p: any P) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:15--1:16=<#generic parameter name#>}} {{-1:11--1:15=}} {{-1:7--1:7=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:15--1:16=some P}} {{-1:11--1:15=}} {{none}} } init(p: any P, t: T) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:21--1:22=<#generic parameter name#>}} {{-1:17--1:21=}} {{-1:12--1:12=, <#generic parameter name#>: P}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:21--1:22=some P}} {{-1:17--1:21=}} {{none}} } subscript(p: any P) -> any P { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:20--1:21=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P>}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-1:20--1:21=some P}} {{-1:16--1:20=}} {{none}} return p } subscript(p: any P, t: T) -> any P { get { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-2:26--2:27=<#generic parameter name#>}} {{-2:22--2:26=}} {{-2:17--2:17=, <#generic parameter name#>: P}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-2:26--2:27=some P}} {{-2:22--2:26=}} {{none}} return p } set(value) { - p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-6:26--6:27=<#generic parameter name#>}} {{-6:22--6:26=}} {{-6:17--6:17=, <#generic parameter name#>: P}} {{none}} + p.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{-6:26--6:27=some P}} {{-6:22--6:26=}} {{none}} value.method(false) // expected-error {{member 'method' cannot be used on value of type 'any P'; consider using a generic constraint instead}} {{none}} } } subscript(p: any P & Q) -> any P { - _read { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:20--1:25=<#generic parameter name#>}} {{-1:16--1:20=}} {{-1:12--1:12=<<#generic parameter name#>: P & Q>}} {{none}} - _modify { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-2:20--2:25=<#generic parameter name#>}} {{-2:16--2:20=}} {{-2:12--2:12=<<#generic parameter name#>: P & Q>}} {{none}} - willSet { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-3:20--3:25=<#generic parameter name#>}} {{-3:16--3:20=}} {{-3:12--3:12=<<#generic parameter name#>: P & Q>}} {{none}} - didSet { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-4:20--4:25=<#generic parameter name#>}} {{-4:16--4:20=}} {{-4:12--4:12=<<#generic parameter name#>: P & Q>}} {{none}} + _read { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-1:20--1:25=some P & Q}} {{-1:16--1:20=}} {{none}} + _modify { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-2:20--2:25=some P & Q}} {{-2:16--2:20=}} {{none}} + willSet { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-3:20--3:25=some P & Q}} {{-3:16--3:20=}} {{none}} + didSet { p.method(false) } // expected-error {{member 'method' cannot be used on value of type 'any P & Q'; consider using a generic constraint instead}} {{-4:20--4:25=some P & Q}} {{-4:16--4:20=}} {{none}} // expected-error@-2 {{'willSet' is not allowed in subscripts}} // expected-error@-2 {{'didSet' is not allowed in subscripts}} }