AST: Fix crash when type parameter is substituted with an existential

getContextSubstitutionMap() didn't handle the case where getAnyNominal()
returns a ProtocolDecl. This should not take the "fast path", which is
only suitable for concrete nominals.

This manifested as a crash-on-invalid -- the user probably meant to write
"T.Value: Collection" rather than "T.Value == Collection".

Fixes rdar://151479861.
This commit is contained in:
Slava Pestov
2025-06-02 17:31:01 -04:00
parent e1e9f04398
commit d8e418a0f9
2 changed files with 16 additions and 1 deletions

View File

@@ -753,7 +753,9 @@ TypeBase::getContextSubstitutions(const DeclContext *dc,
SubstitutionMap TypeBase::getContextSubstitutionMap(
const DeclContext *dc,
GenericEnvironment *genericEnv) {
if (dc == getAnyNominal() && genericEnv == nullptr)
auto *nominal = getAnyNominal();
if (dc == nominal && !isa<ProtocolDecl>(nominal) &&
genericEnv == nullptr)
return getContextSubstitutionMap();
auto genericSig = dc->getGenericSignatureOfContext();

View File

@@ -0,0 +1,13 @@
// RUN: %target-typecheck-verify-swift
protocol P1 {
associatedtype Value
}
protocol P2 {
typealias A = Int
}
struct G<T: P1> where T.Value == any Collection, T.Value.Element: P2 {}
// expected-error@-1 {{cannot access associated type 'Element' from 'any Collection'; use a concrete type or generic parameter base instead}}