From 43e82b4f7ef246ff99f95dc1f759c32712890423 Mon Sep 17 00:00:00 2001 From: Anthony Latsis Date: Tue, 11 Feb 2025 14:30:40 +0000 Subject: [PATCH] Sema: Partially revert existential opening fix Selectively revert 36683a804c6829dc58aed151793a8c5ef72f64a9 to resolve a source compatibility regression. See inline comment for use case. We are going to consider acknowledging this use case in the rules in a future release. --- lib/Sema/OpenedExistentials.cpp | 21 ++++++++++++++----- .../opened_existentials_default_arg.swift | 11 ++++++++++ .../existential_member_access/misc.swift | 13 ------------ ...al-member-access-invariant-pack-type.swift | 12 +++++++++++ 4 files changed, 39 insertions(+), 18 deletions(-) create mode 100644 test/Constraints/opened_existentials_default_arg.swift create mode 100644 validation-test/compiler_crashers_2/existential-member-access-invariant-pack-type.swift diff --git a/lib/Sema/OpenedExistentials.cpp b/lib/Sema/OpenedExistentials.cpp index b1d7a76c9a5b0..ba33af1ca9da6 100644 --- a/lib/Sema/OpenedExistentials.cpp +++ b/lib/Sema/OpenedExistentials.cpp @@ -256,11 +256,22 @@ findGenericParameterReferencesRec(CanGenericSignature genericSig, if (auto *pack = type->getAs()) { auto info = GenericParameterReferenceInfo(); - for (auto arg : pack->getElementTypes()) { - info |= findGenericParameterReferencesRec( - genericSig, origParam, openedParam, arg, - TypePosition::Invariant, /*canBeCovariantResult=*/false); - } + // FIXME: Source compatibility remedy to allow existential opening in + // the following case: + // ``` + // protocol P {} + // struct S {} + // func foo(_: T, _: S? = nil) {} + // let p: any P + // foo(p) + // ``` + // + // for (auto arg : pack->getElementTypes()) { + // info |= findGenericParameterReferencesRec( + // genericSig, origParam, openedParam, arg, + // TypePosition::Invariant, /*canBeCovariantResult=*/false); + // } + (void)pack; return info; } diff --git a/test/Constraints/opened_existentials_default_arg.swift b/test/Constraints/opened_existentials_default_arg.swift new file mode 100644 index 0000000000000..fa5366ad88744 --- /dev/null +++ b/test/Constraints/opened_existentials_default_arg.swift @@ -0,0 +1,11 @@ +// RUN: %target-typecheck-verify-swift -target %target-swift-5.9-abi-triple + +do { + protocol P {} + struct S {} + + func foo(_: T, _: Optional> = nil) {} + + let p: any P + foo(p) // OK +} diff --git a/test/decl/protocol/existential_member_access/misc.swift b/test/decl/protocol/existential_member_access/misc.swift index 4b42123cb8df6..4aa1e4568df62 100644 --- a/test/decl/protocol/existential_member_access/misc.swift +++ b/test/decl/protocol/existential_member_access/misc.swift @@ -50,19 +50,6 @@ func bar(a: any HasSameShape) -> (Int, String) { a.foo(t: 1, u: "hi") } -// Make sure we look through a pack type when evaluating the variance of the result -struct Variadic {} - -protocol VariadicResult { - associatedtype A - func foo() -> Variadic -} - -func variadicResult(a: any VariadicResult) { - a.foo() - // expected-error@-1 {{member 'foo' cannot be used on value of type 'any VariadicResult'; consider using a generic constraint instead}} -} - // Pack expansions are invariant struct Pair {} diff --git a/validation-test/compiler_crashers_2/existential-member-access-invariant-pack-type.swift b/validation-test/compiler_crashers_2/existential-member-access-invariant-pack-type.swift new file mode 100644 index 0000000000000..cd808d0ae02ae --- /dev/null +++ b/validation-test/compiler_crashers_2/existential-member-access-invariant-pack-type.swift @@ -0,0 +1,12 @@ +// RUN: not --crash %target-swift-frontend -typecheck -target %target-swift-5.9-abi-triple %s + +struct Variadic {} + +protocol VariadicResult { + associatedtype A + func foo() -> Variadic +} + +func variadicResult(a: any VariadicResult) { + a.foo() +}