From e71788d7a6cf1992210efff67fae999b1d8ab6d7 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 23 Feb 2017 13:41:08 -0800 Subject: [PATCH 1/2] [GenericSigBuilder] Conformances due to concrete types can be abstract. When a type parameter is made concrete via an existential type, conformance requirements on that type parameter will be abstract. Fixes rdar://problem/30610428. --- lib/AST/GenericSignatureBuilder.cpp | 7 ++++++- test/Generics/requirement_inference.swift | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp index 394fec2a2d34a..5ee80b09dbc28 100644 --- a/lib/AST/GenericSignatureBuilder.cpp +++ b/lib/AST/GenericSignatureBuilder.cpp @@ -1934,10 +1934,15 @@ bool GenericSignatureBuilder::addSameTypeRequirementToConcrete( conformances.insert({protocol, *conformance}); + // Abstract conformances are acceptable for existential types. + assert(conformance->isConcrete() || Concrete->isExistentialType()); + // Update the requirement source now that we know it's concrete. // FIXME: Bad concrete source info. auto concreteSource = Source->viaConcrete(*this, - conformance->getConcrete()); + conformance->isConcrete() + ? conformance->getConcrete() + : nullptr); updateRequirementSource(conforms.second, concreteSource); } } diff --git a/test/Generics/requirement_inference.swift b/test/Generics/requirement_inference.swift index b9b558c85a255..2491c55ee845e 100644 --- a/test/Generics/requirement_inference.swift +++ b/test/Generics/requirement_inference.swift @@ -230,3 +230,20 @@ struct X11 where T.B == U.B.A { // CHECK: Canonical generic signature: <τ_0_0, τ_0_1, τ_1_0 where τ_0_0 : P12, τ_0_1 == X10, τ_0_0.B == X10> func upperSameTypeConstraint(_: V) where U == X10 { } } + +#if _runtime(_ObjC) +// rdar://problem/30610428 +@objc protocol P14 { } + +class X12 { + func bar(v: V) where S == P14 { + } +} + +@objc protocol P15: P14 { } + +class X13 { + func bar(v: V) where S == P15 { + } +} +#endif From cbbf4154359f62c628f1b171de253fa4ab1f23e1 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Thu, 23 Feb 2017 13:43:18 -0800 Subject: [PATCH 2/2] [GenericSigBuilder] Archetypes no longer make it to this path. NFC --- lib/AST/GenericSignatureBuilder.cpp | 52 ++++++++++++++--------------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/lib/AST/GenericSignatureBuilder.cpp b/lib/AST/GenericSignatureBuilder.cpp index 5ee80b09dbc28..ca46d570dc0db 100644 --- a/lib/AST/GenericSignatureBuilder.cpp +++ b/lib/AST/GenericSignatureBuilder.cpp @@ -1916,37 +1916,35 @@ bool GenericSignatureBuilder::addSameTypeRequirementToConcrete( // Make sure the concrete type fulfills the requirements on the archetype. // FIXME: Move later... DenseMap conformances; - if (!Concrete->is()) { - CanType depTy = rep->getDependentType({ }, /*allowUnresolved=*/true) - ->getCanonicalType(); - for (auto &conforms : rep->getConformsTo()) { - auto protocol = conforms.first; - auto conformance = - getLookupConformanceFn()(depTy, Concrete, - protocol->getDeclaredInterfaceType() - ->castTo()); - if (!conformance) { - Diags.diagnose(Source->getLoc(), - diag::requires_generic_param_same_type_does_not_conform, - Concrete, protocol->getName()); - return true; - } + CanType depTy = rep->getDependentType({ }, /*allowUnresolved=*/true) + ->getCanonicalType(); + for (auto &conforms : rep->getConformsTo()) { + auto protocol = conforms.first; + auto conformance = + getLookupConformanceFn()(depTy, Concrete, + protocol->getDeclaredInterfaceType() + ->castTo()); + if (!conformance) { + Diags.diagnose(Source->getLoc(), + diag::requires_generic_param_same_type_does_not_conform, + Concrete, protocol->getName()); + return true; + } - conformances.insert({protocol, *conformance}); + conformances.insert({protocol, *conformance}); - // Abstract conformances are acceptable for existential types. - assert(conformance->isConcrete() || Concrete->isExistentialType()); + // Abstract conformances are acceptable for existential types. + assert(conformance->isConcrete() || Concrete->isExistentialType()); - // Update the requirement source now that we know it's concrete. - // FIXME: Bad concrete source info. - auto concreteSource = Source->viaConcrete(*this, - conformance->isConcrete() - ? conformance->getConcrete() - : nullptr); - updateRequirementSource(conforms.second, concreteSource); - } + // Update the requirement source now that we know it's concrete. + // FIXME: Bad concrete source info. + auto concreteSource = Source->viaConcrete(*this, + conformance->isConcrete() + ? conformance->getConcrete() + : nullptr); + updateRequirementSource(conforms.second, concreteSource); } - + // Record the requirement. rep->ConcreteType = Concrete;