Skip to content

Commit 8390872

Browse files
authored
Merge pull request swiftlang#8936 from DougGregor/multi-file-conformance
2 parents fbc7858 + 449aa2f commit 8390872

File tree

7 files changed

+63
-14
lines changed

7 files changed

+63
-14
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,7 @@ void AttributeChecker::visitSpecializeAttr(SpecializeAttr *attr) {
16301630

16311631
// Form a new generic signature based on the old one.
16321632
GenericSignatureBuilder Builder(D->getASTContext(),
1633-
LookUpConformanceInModule(DC->getParentModule()));
1633+
TypeChecker::LookUpConformance(TC, DC));
16341634

16351635
// First, add the old generic signature.
16361636
Builder.addGenericSignature(genericSig);

lib/Sema/TypeCheckGeneric.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -797,8 +797,7 @@ TypeChecker::validateGenericFuncSignature(AbstractFunctionDecl *func) {
797797
addGenericParamTypes(gp, allGenericParams);
798798

799799
// Create the generic signature builder.
800-
GenericSignatureBuilder builder(Context,
801-
LookUpConformanceInModule(func->getParentModule()));
800+
GenericSignatureBuilder builder(Context, LookUpConformance(*this, func));
802801

803802
// Type check the function declaration, treating all generic type
804803
// parameters as dependent, unresolved.
@@ -1028,8 +1027,7 @@ TypeChecker::validateGenericSubscriptSignature(SubscriptDecl *subscript) {
10281027
addGenericParamTypes(gp, allGenericParams);
10291028

10301029
// Create the generic signature builder.
1031-
GenericSignatureBuilder builder(Context,
1032-
LookUpConformanceInModule(subscript->getParentModule()));
1030+
GenericSignatureBuilder builder(Context, LookUpConformance(*this, subscript));
10331031

10341032
// Type check the function declaration, treating all generic type
10351033
// parameters as dependent, unresolved.
@@ -1148,7 +1146,7 @@ GenericEnvironment *TypeChecker::checkGenericEnvironment(
11481146

11491147
// Create the generic signature builder.
11501148
ModuleDecl *module = dc->getParentModule();
1151-
GenericSignatureBuilder builder(Context, LookUpConformanceInModule(module));
1149+
GenericSignatureBuilder builder(Context, LookUpConformance(*this, dc));
11521150

11531151
// Type check the generic parameters, treating all generic type
11541152
// parameters as dependent, unresolved.

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,12 +1017,13 @@ RequirementEnvironment::RequirementEnvironment(
10171017
auto selfType = cast<GenericTypeParamType>(
10181018
proto->getSelfInterfaceType()->getCanonicalType());
10191019

1020-
// Construct a generic signature builder by collecting the constraints from the
1021-
// requirement and the context of the conformance together, because both
1022-
// define the capabilities of the requirement.
1020+
// Construct a generic signature builder by collecting the constraints
1021+
// from the requirement and the context of the conformance together,
1022+
// because both define the capabilities of the requirement.
10231023
GenericSignatureBuilder builder(
10241024
ctx,
1025-
LookUpConformanceInModule(conformanceDC->getParentModule()));
1025+
TypeChecker::LookUpConformance(tc, conformanceDC));
1026+
10261027
SmallVector<GenericTypeParamType*, 4> allGenericParams;
10271028

10281029
// Add the generic signature of the context of the conformance. This includes
@@ -4836,8 +4837,7 @@ void ConformanceChecker::ensureRequirementsAreSatisfied() {
48364837
// FIXME: maybe this should be the conformance's type
48374838
proto->getDeclaredInterfaceType(), reqSig,
48384839
QuerySubstitutionMap{substitutions},
4839-
LookUpConformanceInModule(
4840-
Conformance->getDeclContext()->getParentModule()),
4840+
TypeChecker::LookUpConformance(TC, Conformance->getDeclContext()),
48414841
nullptr,
48424842
ConformanceCheckFlags::Used, &listener);
48434843

@@ -5328,6 +5328,21 @@ TypeChecker::conformsToProtocol(Type T, ProtocolDecl *Proto, DeclContext *DC,
53285328
: ConformsToProtocolResult::failure();
53295329
}
53305330

5331+
Optional<ProtocolConformanceRef>
5332+
TypeChecker::LookUpConformance::operator()(
5333+
CanType dependentType,
5334+
Type conformingReplacementType,
5335+
ProtocolType *conformedProtocol) const {
5336+
if (conformingReplacementType->isTypeParameter())
5337+
return ProtocolConformanceRef(conformedProtocol->getDecl());
5338+
5339+
return tc.conformsToProtocol(conformingReplacementType,
5340+
conformedProtocol->getDecl(),
5341+
dc,
5342+
(ConformanceCheckFlags::Used|
5343+
ConformanceCheckFlags::InExpression));
5344+
}
5345+
53315346
/// Mark any _ObjectiveCBridgeable conformances in the given type as "used".
53325347
///
53335348
/// These conformances might not appear in any substitution lists produced

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ Type TypeChecker::applyUnboundGenericArguments(
742742
auto result =
743743
checkGenericArguments(dc, loc, noteLoc, unboundType, genericSig,
744744
QueryTypeSubstitutionMap{subs},
745-
LookUpConformanceInModule{dc->getParentModule()},
745+
LookUpConformance(*this, dc),
746746
unsatisfiedDependency);
747747

748748
switch (result) {
@@ -757,7 +757,7 @@ Type TypeChecker::applyUnboundGenericArguments(
757757

758758
// Apply the substitution map to the interface type of the declaration.
759759
resultType = resultType.subst(QueryTypeSubstitutionMap{subs},
760-
LookUpConformanceInModule(dc->getParentModule()),
760+
LookUpConformance(*this, dc),
761761
SubstFlags::UseErrorType);
762762

763763
if (isa<NominalTypeDecl>(decl)) {

lib/Sema/TypeChecker.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,23 @@ class TypeChecker final : public LazyResolver {
18191819
ConformanceCheckOptions options, SourceLoc ComplainLoc,
18201820
UnsatisfiedDependency *unsatisfiedDependency);
18211821

1822+
/// Functor class suitable for use as a \c LookupConformanceFn to look up a
1823+
/// conformance through a particular declaration context using the given
1824+
/// type checker.
1825+
class LookUpConformance {
1826+
TypeChecker &tc;
1827+
DeclContext *dc;
1828+
1829+
public:
1830+
explicit LookUpConformance(TypeChecker &tc, DeclContext *dc)
1831+
: tc(tc), dc(dc) { }
1832+
1833+
Optional<ProtocolConformanceRef>
1834+
operator()(CanType dependentType,
1835+
Type conformingReplacementType,
1836+
ProtocolType *conformedProtocol) const;
1837+
};
1838+
18221839
/// Completely check the given conformance.
18231840
void checkConformance(NormalProtocolConformance *conformance);
18241841

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
protocol _P { }
2+
protocol P : _P { }
3+
4+
protocol Q {
5+
associatedtype A: P
6+
7+
func getArray() -> [RequiresP<A>]
8+
}
9+
10+
struct RequiresP<T: P> { }
11+
12+
struct MyStruct: P { }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-swift-frontend -emit-ir %S/Inputs/for_each_conformance_crashB.swift -primary-file %s -o -
2+
3+
extension Q where A == MyStruct {
4+
func foo() {
5+
for _ in getArray() { }
6+
}
7+
}

0 commit comments

Comments
 (0)