From 5248550bc00a3db760e247ae6c142816f1efa265 Mon Sep 17 00:00:00 2001 From: zoecarver Date: Wed, 30 Oct 2019 17:04:04 -0700 Subject: [PATCH 1/2] Resolve collisions when typealias used in associatedtype constraint Uses Anthony's fix (3c87252) to resolve collisions --- lib/Sema/TypeCheckType.cpp | 21 ++++++++++++++----- .../compiler_crashers_2_fixed/sr11639.swift | 16 ++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 validation-test/compiler_crashers_2_fixed/sr11639.swift diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index a5ed86edb2b5b..70b6462f37bc7 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -565,9 +565,7 @@ Type TypeChecker::resolveTypeInContext(TypeDecl *typeDecl, DeclContext *foundDC, if (selfType->is()) { if (typeDecl->getDeclContext()->getSelfProtocolDecl()) { - if (isa(typeDecl) || - (isa(typeDecl) && - !cast(typeDecl)->isGeneric())) { + if (isa(typeDecl)) { // FIXME: We should use this lookup method for the Interface // stage too, but right now that causes problems with // Sequence.SubSequence vs Collection.SubSequence; the former @@ -1295,10 +1293,23 @@ resolveTopLevelIdentTypeComponent(TypeResolution resolution, // Otherwise, check for an ambiguity. if (!resolution.areSameType(current, type)) { isAmbiguous = true; - break; + // If a typealias collides with an associatedtype in generic requirement + // position, prefer the associated type. + if (options.getContext() == TypeResolverContext::GenericRequirement) { + if (isa(currentDecl) && isa(typeDecl)) { + current = type; + currentDecl = typeDecl; + currentDC = foundDC; + isAmbiguous = false; + } else if (isa(currentDecl) && + isa(typeDecl)) { + isAmbiguous = false; + } + } + if (isAmbiguous) break; } - // We have a found multiple type aliases that refer to the same thing. + // We have found multiple type aliases that refer to the same thing. // Ignore the duplicate. } diff --git a/validation-test/compiler_crashers_2_fixed/sr11639.swift b/validation-test/compiler_crashers_2_fixed/sr11639.swift new file mode 100644 index 0000000000000..1f8633c0937a5 --- /dev/null +++ b/validation-test/compiler_crashers_2_fixed/sr11639.swift @@ -0,0 +1,16 @@ +// RUN: not %target-typecheck-verify-swift + +protocol ProtocolA { + associatedtype T1 +} + +struct S : ProtocolA { + typealias T1 = T +} + +protocol ProtocolB: ProtocolA { + associatedtype T2: ProtocolB where T2.T1 == T3.T1 + associatedtype X + typealias T3 = S +} + From ca5e247ce407347918d54ab9281bbbb27b5c138f Mon Sep 17 00:00:00 2001 From: zoecarver Date: Sat, 9 Nov 2019 16:45:56 -0800 Subject: [PATCH 2/2] stash --- lib/AST/GenericSignatureBuilder.cpp | 19 +++++++++++++++++++ lib/Sema/TypeCheckType.cpp | 12 ++++++++++-- .../compiler_crashers_2_fixed/sr11639.swift | 2 +- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp index 4b08216270f95..136106b9c69c2 100644 --- a/lib/AST/GenericSignatureBuilder.cpp +++ b/lib/AST/GenericSignatureBuilder.cpp @@ -48,6 +48,8 @@ #include "llvm/Support/SaveAndRestore.h" #include +#include + using namespace swift; using llvm::DenseMap; @@ -3625,6 +3627,8 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass( Type type, ArchetypeResolutionKind resolutionKind, bool wantExactPotentialArchetype) { + type->dump(); + // An error type is best modeled as an unresolved potential archetype, since // there's no way to be sure what it is actually meant to be. if (type->is()) { @@ -3633,12 +3637,16 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass( // The equivalence class of a generic type is known directly. if (auto genericParam = type->getAs()) { + std::cout << "0" << std::endl; unsigned index = GenericParamKey(genericParam).findIndexIn( getGenericParams()); + std::cout << "1" << std::endl; if (index < Impl->GenericParams.size()) { + std::cout << "2" << std::endl; return ResolvedType(Impl->PotentialArchetypes[index]); } + std::cout << "3" << std::endl; return ResolvedType::forUnresolved(nullptr); } @@ -3646,6 +3654,7 @@ ResolvedType GenericSignatureBuilder::maybeResolveEquivalenceClass( // base equivalence class, if there is one. if (auto depMemTy = type->getAs()) { // Find the equivalence class of the base. + std::cout << "4" << std::endl; auto resolvedBase = maybeResolveEquivalenceClass(depMemTy->getBase(), resolutionKind, @@ -4850,6 +4859,16 @@ ConstraintResult GenericSignatureBuilder::addSameTypeRequirement( FloatingRequirementSource source, UnresolvedHandlingKind unresolvedHandling, llvm::function_ref diagnoseMismatch) { + + if (paOrT1.is()) + paOrT1.get()->dump(); + if (paOrT1.is()) + paOrT1.get()->dump(); + + if (paOrT2.is()) + paOrT2.get()->dump(); + if (paOrT2.is()) + paOrT2.get()->dump(); auto resolved1 = resolve(paOrT1, source); if (!resolved1) { diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 70b6462f37bc7..23272fe63c7cf 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -47,6 +47,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/SaveAndRestore.h" +#include using namespace swift; @@ -565,7 +566,8 @@ Type TypeChecker::resolveTypeInContext(TypeDecl *typeDecl, DeclContext *foundDC, if (selfType->is()) { if (typeDecl->getDeclContext()->getSelfProtocolDecl()) { - if (isa(typeDecl)) { + if (isa(typeDecl) || + typeDecl->getAsGenericContext()) { // FIXME: We should use this lookup method for the Interface // stage too, but right now that causes problems with // Sequence.SubSequence vs Collection.SubSequence; the former @@ -574,10 +576,16 @@ Type TypeChecker::resolveTypeInContext(TypeDecl *typeDecl, DeclContext *foundDC, // because we use the Sequence.SubSequence default instead of // the Collection.SubSequence default, even when the conforming // type wants to conform to Collection. +// selfType->dump(); +// typeDecl->dump(); +// std::cout << typeDecl->getName().get() << std::endl; + if (resolution.getStage() == TypeResolutionStage::Structural) { return resolution.resolveSelfAssociatedType(selfType, foundDC, typeDecl->getName()); - } else if (auto assocType = dyn_cast(typeDecl)) { + } + + if (auto assocType = dyn_cast(typeDecl)) { typeDecl = assocType->getAssociatedTypeAnchor(); } } diff --git a/validation-test/compiler_crashers_2_fixed/sr11639.swift b/validation-test/compiler_crashers_2_fixed/sr11639.swift index 1f8633c0937a5..4d0cca842c837 100644 --- a/validation-test/compiler_crashers_2_fixed/sr11639.swift +++ b/validation-test/compiler_crashers_2_fixed/sr11639.swift @@ -1,4 +1,4 @@ -// RUN: not %target-typecheck-verify-swift +// RUN: %target-typecheck-verify-swift protocol ProtocolA { associatedtype T1