From aa9aa58cea7ede42fec0ff3e2595f33e282ca37a Mon Sep 17 00:00:00 2001 From: Hamish Knight Date: Wed, 17 Sep 2025 15:23:08 +0100 Subject: [PATCH] [Sema] Handle PlaceholderTypes in associated type inference Avoid attempting to infer an associatedtype as a type that contains placeholders. --- include/swift/AST/TypeMatcher.h | 6 ++++++ lib/Sema/AssociatedTypeInference.cpp | 6 +++--- .../ac7123f2338b128.swift | 2 +- .../c8563a4a60b27cf3.swift | 2 +- 4 files changed, 11 insertions(+), 5 deletions(-) rename validation-test/{compiler_crashers_2 => compiler_crashers_2_fixed}/ac7123f2338b128.swift (85%) rename validation-test/{compiler_crashers_2 => compiler_crashers_2_fixed}/c8563a4a60b27cf3.swift (90%) diff --git a/include/swift/AST/TypeMatcher.h b/include/swift/AST/TypeMatcher.h index ab6d90eb219..fcaf361a918 100644 --- a/include/swift/AST/TypeMatcher.h +++ b/include/swift/AST/TypeMatcher.h @@ -117,6 +117,12 @@ private: #define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type) #include "swift/AST/TypeNodes.def" + bool visitPlaceholderType(CanPlaceholderType firstType, Type secondType, + Type sugaredFirstType) { + // Placeholder types never match. + return mismatch(firstType.getPointer(), secondType, sugaredFirstType); + } + bool visitUnresolvedType(CanUnresolvedType firstType, Type secondType, Type sugaredFirstType) { // Unresolved types never match. diff --git a/lib/Sema/AssociatedTypeInference.cpp b/lib/Sema/AssociatedTypeInference.cpp index 665b8af1178..81c9ddad13b 100644 --- a/lib/Sema/AssociatedTypeInference.cpp +++ b/lib/Sema/AssociatedTypeInference.cpp @@ -2317,9 +2317,9 @@ AssociatedTypeInference::getPotentialTypeWitnessesByMatchingTypes(ValueDecl *req /// Deduce associated types from dependent member types in the witness. bool mismatch(DependentMemberType *firstDepMember, TypeBase *secondType, Type sugaredFirstType) { - // If the second type is an error, don't look at it further, but proceed - // to find other matches. - if (secondType->hasError()) + // If the second type is an error or placeholder, don't look at it + // further, but proceed to find other matches. + if (secondType->hasError() || secondType->hasPlaceholder()) return true; // If the second type is a generic parameter of the witness, the match diff --git a/validation-test/compiler_crashers_2/ac7123f2338b128.swift b/validation-test/compiler_crashers_2_fixed/ac7123f2338b128.swift similarity index 85% rename from validation-test/compiler_crashers_2/ac7123f2338b128.swift rename to validation-test/compiler_crashers_2_fixed/ac7123f2338b128.swift index a03cccf7a39..584bfa97f36 100644 --- a/validation-test/compiler_crashers_2/ac7123f2338b128.swift +++ b/validation-test/compiler_crashers_2_fixed/ac7123f2338b128.swift @@ -1,5 +1,5 @@ // {"signature":"swift::TypeChecker::typeCheckTarget(swift::constraints::SyntacticElementTarget&, swift::optionset::OptionSet, swift::DiagnosticTransaction*)"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s enum a protocol b { associatedtype c diff --git a/validation-test/compiler_crashers_2/c8563a4a60b27cf3.swift b/validation-test/compiler_crashers_2_fixed/c8563a4a60b27cf3.swift similarity index 90% rename from validation-test/compiler_crashers_2/c8563a4a60b27cf3.swift rename to validation-test/compiler_crashers_2_fixed/c8563a4a60b27cf3.swift index 355fe39c869..97970c53ae7 100644 --- a/validation-test/compiler_crashers_2/c8563a4a60b27cf3.swift +++ b/validation-test/compiler_crashers_2_fixed/c8563a4a60b27cf3.swift @@ -1,5 +1,5 @@ // {"signature":"swift::CanTypeVisitor&, llvm::SmallVectorImpl&, llvm::SmallVectorImpl&)::Matcher>::MatchVisitor, bool, swift::Type, swift::Type>::visit(swift::CanType, swift::Type, swift::Type)"} -// RUN: not --crash %target-swift-frontend -typecheck %s +// RUN: not %target-swift-frontend -typecheck %s protocol a { associatedtype b associatedtype c associatedtype d func e(b, c) -> d }