From fda2ddb86a087c6b711957d8646bb6a2dad42922 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 2 Mar 2017 23:34:40 -0800 Subject: [PATCH] AST: Targeted fix for conformance lookup issue When substituting a type like T.A.B where A and B are associated types and the conformance requirement on T.A is implied by conformance requirements on T, we would crash. The problem is that we have no way of representing an abstract conformance with nested concrete types. This patch adds a workaround. Fixes and . --- lib/AST/SubstitutionMap.cpp | 16 +++++++++++++++- .../compiler_crashers_2_fixed/0076-sr3500.swift | 12 ++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 validation-test/compiler_crashers_2_fixed/0076-sr3500.swift diff --git a/lib/AST/SubstitutionMap.cpp b/lib/AST/SubstitutionMap.cpp index 7919fe07c9c64..80d87d7a5c9ba 100644 --- a/lib/AST/SubstitutionMap.cpp +++ b/lib/AST/SubstitutionMap.cpp @@ -17,6 +17,7 @@ #include "swift/AST/ASTContext.h" #include "swift/AST/SubstitutionMap.h" #include "swift/AST/Decl.h" +#include "swift/AST/Module.h" #include "swift/AST/ProtocolConformance.h" #include "swift/AST/Types.h" @@ -70,7 +71,8 @@ SubstitutionMap::lookupConformance(CanType type, } // Check if we have substitutions from one of our parent types. - return forEachParent(type, [&](CanType parent, AssociatedTypeDecl *assocType) + auto result = forEachParent(type, + [&](CanType parent, AssociatedTypeDecl *assocType) -> Optional { auto *parentProto = assocType->getProtocol(); @@ -87,6 +89,18 @@ SubstitutionMap::lookupConformance(CanType type, return lookupConformance(proto, sub.getConformances()); }); + + // FIXME: Narrow fix for broken conformance lookup + if (!result || result->isAbstract()) { + auto substTy = type.subst(*this); + if (!substTy) + return result; + + auto *M = proto->getParentModule(); + return M->lookupConformance(substTy, proto, nullptr); + } + + return result; } void SubstitutionMap:: diff --git a/validation-test/compiler_crashers_2_fixed/0076-sr3500.swift b/validation-test/compiler_crashers_2_fixed/0076-sr3500.swift new file mode 100644 index 0000000000000..f93111211fcd4 --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/0076-sr3500.swift @@ -0,0 +1,12 @@ +// RUN: %target-swift-frontend %s -emit-ir + +protocol A { + associatedtype Coordinate: Strideable + func doSomething(_: Range) -> Coordinate.Stride +} + +extension A where Coordinate == Int { + func extensionFunc(_ range: Range) { + _ = doSomething(range) + } +}