[Sema] Handle PlaceholderTypes in associated type inference

Avoid attempting to infer an associatedtype as a type that contains
placeholders.
This commit is contained in:
Hamish Knight
2025-09-17 15:23:08 +01:00
parent d1b8084bc1
commit aa9aa58cea
4 changed files with 11 additions and 5 deletions

View File

@@ -117,6 +117,12 @@ private:
#define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type) #define SINGLETON_TYPE(SHORT_ID, ID) TRIVIAL_CASE(ID##Type)
#include "swift/AST/TypeNodes.def" #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, bool visitUnresolvedType(CanUnresolvedType firstType, Type secondType,
Type sugaredFirstType) { Type sugaredFirstType) {
// Unresolved types never match. // Unresolved types never match.

View File

@@ -2317,9 +2317,9 @@ AssociatedTypeInference::getPotentialTypeWitnessesByMatchingTypes(ValueDecl *req
/// Deduce associated types from dependent member types in the witness. /// Deduce associated types from dependent member types in the witness.
bool mismatch(DependentMemberType *firstDepMember, bool mismatch(DependentMemberType *firstDepMember,
TypeBase *secondType, Type sugaredFirstType) { TypeBase *secondType, Type sugaredFirstType) {
// If the second type is an error, don't look at it further, but proceed // If the second type is an error or placeholder, don't look at it
// to find other matches. // further, but proceed to find other matches.
if (secondType->hasError()) if (secondType->hasError() || secondType->hasPlaceholder())
return true; return true;
// If the second type is a generic parameter of the witness, the match // If the second type is a generic parameter of the witness, the match

View File

@@ -1,5 +1,5 @@
// {"signature":"swift::TypeChecker::typeCheckTarget(swift::constraints::SyntacticElementTarget&, swift::optionset::OptionSet<swift::TypeCheckExprFlags, unsigned int>, swift::DiagnosticTransaction*)"} // {"signature":"swift::TypeChecker::typeCheckTarget(swift::constraints::SyntacticElementTarget&, swift::optionset::OptionSet<swift::TypeCheckExprFlags, unsigned int>, swift::DiagnosticTransaction*)"}
// RUN: not --crash %target-swift-frontend -typecheck %s // RUN: not %target-swift-frontend -typecheck %s
enum a enum a
protocol b { protocol b {
associatedtype c associatedtype c

View File

@@ -1,5 +1,5 @@
// {"signature":"swift::CanTypeVisitor<swift::TypeMatcher<desugarSameTypeRequirement(swift::Requirement, swift::SourceLoc, llvm::SmallVectorImpl<swift::Requirement>&, llvm::SmallVectorImpl<swift::InverseRequirement>&, llvm::SmallVectorImpl<swift::rewriting::RequirementError>&)::Matcher>::MatchVisitor, bool, swift::Type, swift::Type>::visit(swift::CanType, swift::Type, swift::Type)"} // {"signature":"swift::CanTypeVisitor<swift::TypeMatcher<desugarSameTypeRequirement(swift::Requirement, swift::SourceLoc, llvm::SmallVectorImpl<swift::Requirement>&, llvm::SmallVectorImpl<swift::InverseRequirement>&, llvm::SmallVectorImpl<swift::rewriting::RequirementError>&)::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 { protocol a {
associatedtype b associatedtype c associatedtype d func e(b, c) -> d associatedtype b associatedtype c associatedtype d func e(b, c) -> d
} }