From 0fc095c775671b99f2a0d19fd198139766d13928 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Thu, 16 Jun 2016 03:17:57 -0700 Subject: [PATCH] Sema: Re-arrange deck chairs again Another pre-emptive compiler_crasher regression fix. I have an idea for consolidating some of these hacky circularity checks in a nice way, but not now. --- lib/Sema/ITCDecl.cpp | 13 ++++++---- lib/Sema/TypeCheckProtocol.cpp | 24 ++++++++++++------- ...5-swift-typechecker-checkconformance.swift | 2 +- 3 files changed, 24 insertions(+), 15 deletions(-) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28225-swift-typechecker-checkconformance.swift (88%) diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp index 1371b77b31bc0..3c947e0593196 100644 --- a/lib/Sema/ITCDecl.cpp +++ b/lib/Sema/ITCDecl.cpp @@ -244,10 +244,6 @@ void IterativeTypeChecker::processInheritedProtocols( if (anyDependencies) return; - // FIXME: Hack to deal with recursion elsewhere. - if (protocol->isInheritedProtocolsValid()) - return; - // Check for circular inheritance. // FIXME: The diagnostics here should be improved... and this should probably // be handled by the normal cycle detection. @@ -255,7 +251,8 @@ void IterativeTypeChecker::processInheritedProtocols( for (unsigned i = 0, n = allProtocols.size(); i != n; /*in loop*/) { if (allProtocols[i] == protocol || allProtocols[i]->inheritsFrom(protocol)) { - if (!diagnosedCircularity) { + if (!diagnosedCircularity && + !protocol->isInheritedProtocolsValid()) { diagnose(protocol, diag::circular_protocol_def, protocol->getName().str()); diagnosedCircularity = true; @@ -269,6 +266,12 @@ void IterativeTypeChecker::processInheritedProtocols( ++i; } + // FIXME: Hack to deal with recursion elsewhere. + // We recurse through DeclContext::getLocalProtocols() -- this should be + // redone to use the IterativeDeclChecker also. + if (protocol->isInheritedProtocolsValid()) + return; + protocol->setInheritedProtocols(getASTContext().AllocateCopy(allProtocols)); } diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 5e1d1cc6849cb..e089ca42abc40 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -1807,15 +1807,21 @@ static Substitution getArchetypeSubstitution(TypeChecker &tc, SmallVector conformances; bool isError = replacement->is(); - for (auto proto : archetype->getConformsTo()) { - ProtocolConformance *conformance = nullptr; - bool conforms = tc.conformsToProtocol(replacement, proto, dc, None, - &conformance); - assert((conforms || isError) && - "Conformance should already have been verified"); - (void)isError; - (void)conforms; - conformances.push_back(ProtocolConformanceRef(proto, conformance)); + assert((archetype != nullptr || isError) && + "Should have built archetypes already"); + + // FIXME: Turn the nullptr check into an assertion + if (archetype != nullptr) { + for (auto proto : archetype->getConformsTo()) { + ProtocolConformance *conformance = nullptr; + bool conforms = tc.conformsToProtocol(replacement, proto, dc, None, + &conformance); + assert((conforms || isError) && + "Conformance should already have been verified"); + (void)isError; + (void)conforms; + conformances.push_back(ProtocolConformanceRef(proto, conformance)); + } } return Substitution{ diff --git a/validation-test/compiler_crashers/28225-swift-typechecker-checkconformance.swift b/validation-test/compiler_crashers_fixed/28225-swift-typechecker-checkconformance.swift similarity index 88% rename from validation-test/compiler_crashers/28225-swift-typechecker-checkconformance.swift rename to validation-test/compiler_crashers_fixed/28225-swift-typechecker-checkconformance.swift index a73d33543d7f7..43860510f80f5 100644 --- a/validation-test/compiler_crashers/28225-swift-typechecker-checkconformance.swift +++ b/validation-test/compiler_crashers_fixed/28225-swift-typechecker-checkconformance.swift @@ -5,6 +5,6 @@ // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -parse +// RUN: not %target-swift-frontend %s -parse func e{enum k:A}protocol A{associatedtype B:A associatedtype n