Skip to content

Commit f5087c4

Browse files
authored
Merge pull request #81202 from slavapestov/lookup-conformance-fn
AST: Change signature of LookupConformanceFn
2 parents 158b1c5 + e3c8f42 commit f5087c4

16 files changed

+157
-195
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,9 @@ class LookUpConformanceInSubstitutionMap {
294294
explicit LookUpConformanceInSubstitutionMap(SubstitutionMap Subs)
295295
: Subs(Subs) {}
296296

297-
ProtocolConformanceRef operator()(CanType dependentType,
298-
Type conformingReplacementType,
299-
ProtocolDecl *conformedProtocol) const;
297+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
298+
Type dependentType,
299+
ProtocolDecl *proto) const;
300300
};
301301

302302
struct OverrideSubsInfo {
@@ -326,8 +326,8 @@ struct LookUpConformanceInOverrideSubs {
326326
explicit LookUpConformanceInOverrideSubs(const OverrideSubsInfo &info)
327327
: info(info) {}
328328

329-
ProtocolConformanceRef operator()(CanType type,
330-
Type substType,
329+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
330+
Type dependentType,
331331
ProtocolDecl *proto) const;
332332
};
333333

@@ -338,9 +338,9 @@ struct OuterSubstitutions {
338338
unsigned depth;
339339

340340
Type operator()(SubstitutableType *type) const;
341-
ProtocolConformanceRef operator()(CanType dependentType,
342-
Type conformingReplacementType,
343-
ProtocolDecl *conformedProtocol) const;
341+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
342+
Type dependentType,
343+
ProtocolDecl *proto) const;
344344
};
345345

346346
} // end namespace swift

include/swift/AST/Type.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ struct QueryTypeSubstitutionMap {
8888
};
8989

9090
/// Function used to resolve conformances.
91-
using GenericFunction = auto(CanType dependentType,
92-
Type conformingReplacementType,
93-
ProtocolDecl *conformedProtocol)
91+
using GenericFunction = auto(InFlightSubstitution &IFS,
92+
Type dependentType,
93+
ProtocolDecl *proto)
9494
-> ProtocolConformanceRef;
9595
using LookupConformanceFn = llvm::function_ref<GenericFunction>;
9696

@@ -100,19 +100,19 @@ class LookUpConformanceInModule {
100100
public:
101101
explicit LookUpConformanceInModule() {}
102102

103-
ProtocolConformanceRef operator()(CanType dependentType,
104-
Type conformingReplacementType,
105-
ProtocolDecl *conformedProtocol) const;
103+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
104+
Type dependentType,
105+
ProtocolDecl *proto) const;
106106
};
107107

108108
/// Functor class suitable for use as a \c LookupConformanceFn that provides
109109
/// only abstract conformances for generic types. Asserts that the replacement
110110
/// type is an opaque generic type.
111111
class MakeAbstractConformanceForGenericType {
112112
public:
113-
ProtocolConformanceRef operator()(CanType dependentType,
114-
Type conformingReplacementType,
115-
ProtocolDecl *conformedProtocol) const;
113+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
114+
Type dependentType,
115+
ProtocolDecl *proto) const;
116116
};
117117

118118
/// Flags that can be passed when substituting into a type.

include/swift/AST/Types.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7069,8 +7069,8 @@ class ReplaceOpaqueTypesWithUnderlyingTypes {
70697069
Type operator()(SubstitutableType *maybeOpaqueType) const;
70707070

70717071
/// LookupConformanceFn
7072-
ProtocolConformanceRef operator()(CanType maybeOpaqueType,
7073-
Type replacementType,
7072+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
7073+
Type maybeOpaqueType,
70747074
ProtocolDecl *protocol) const;
70757075

70767076
OpaqueSubstitutionKind
@@ -7108,8 +7108,8 @@ class ReplaceExistentialArchetypesWithConcreteTypes {
71087108
Type operator()(SubstitutableType *type) const;
71097109

71107110
/// LookupConformanceFn
7111-
ProtocolConformanceRef operator()(CanType origType,
7112-
Type substType,
7111+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
7112+
Type origType,
71137113
ProtocolDecl *protocol) const;
71147114

71157115
};

include/swift/SIL/SILCloner.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,23 @@ struct SubstitutionMapWithLocalArchetypes {
8080
return Type(type);
8181
}
8282

83-
ProtocolConformanceRef operator()(CanType origType,
84-
Type substType,
83+
ProtocolConformanceRef operator()(InFlightSubstitution &IFS,
84+
Type origType,
8585
ProtocolDecl *proto) {
86-
if (isa<LocalArchetypeType>(origType))
87-
return swift::lookupConformance(substType, proto);
86+
if (origType->is<LocalArchetypeType>())
87+
return swift::lookupConformance(origType.subst(IFS), proto);
8888

89-
if (isa<PrimaryArchetypeType>(origType) ||
90-
isa<PackArchetypeType>(origType))
91-
origType = origType->mapTypeOutOfContext()->getCanonicalType();
89+
if (origType->is<PrimaryArchetypeType>() ||
90+
origType->is<PackArchetypeType>())
91+
origType = origType->mapTypeOutOfContext();
9292

93-
if (SubsMap)
94-
return SubsMap->lookupConformance(origType, proto);
93+
if (SubsMap) {
94+
return SubsMap->lookupConformance(
95+
origType->getCanonicalType(), proto);
96+
}
9597

96-
return ProtocolConformanceRef::forAbstract(substType, proto);
98+
return ProtocolConformanceRef::forAbstract(
99+
origType.subst(IFS), proto);
97100
}
98101

99102
void dump(llvm::raw_ostream &out) const {

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,15 +1914,9 @@ void PrintAST::printSingleDepthOfGenericSignature(
19141914
if (subMap.empty())
19151915
return param;
19161916

1917-
return param.subst(
1918-
[&](SubstitutableType *type) -> Type {
1919-
if (cast<GenericTypeParamType>(type)->getDepth() < typeContextDepth)
1920-
return Type(type).subst(subMap);
1921-
return type;
1922-
},
1923-
[&](CanType depType, Type substType, ProtocolDecl *proto) {
1924-
return lookupConformance(substType, proto);
1925-
});
1917+
OuterSubstitutions replacer{subMap, typeContextDepth};
1918+
return param.subst(replacer, replacer,
1919+
SubstFlags::PreservePackExpansionLevel);
19261920
};
19271921

19281922
/// Separate the explicit generic parameters from the implicit, opaque

lib/AST/ExistentialGeneralization.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,11 @@ class Generalizer : public CanTypeVisitor<Generalizer, Type> {
6868
assert(it != substTypes.end());
6969
return it->second;
7070
};
71-
auto lookupConformance = [&](CanType dependentType,
72-
Type conformingReplacementType,
71+
auto lookupConformance = [&](InFlightSubstitution &IFS,
72+
Type dependentType,
7373
ProtocolDecl *conformedProtocol) {
74-
auto it = substConformances.find({dependentType, conformedProtocol});
74+
auto it = substConformances.find(
75+
{dependentType->getCanonicalType(), conformedProtocol});
7576
assert(it != substConformances.end());
7677
return it->second;
7778
};

lib/AST/LocalArchetypeRequirementCollector.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,10 +266,10 @@ swift::buildSubstitutionMapWithCapturedEnvironments(
266266
return mapIntoLocalContext(param, baseDepth, capturedEnvs);
267267
return Type(type).subst(baseSubMap);
268268
},
269-
[&](CanType origType, Type substType,
270-
ProtocolDecl *proto) -> ProtocolConformanceRef {
269+
[&](InFlightSubstitution &IFS, Type origType, ProtocolDecl *proto)
270+
-> ProtocolConformanceRef {
271271
if (origType->getRootGenericParam()->getDepth() >= baseDepth)
272-
return ProtocolConformanceRef::forAbstract(substType, proto);
273-
return baseSubMap.lookupConformance(origType, proto);
272+
return ProtocolConformanceRef::forAbstract(origType.subst(IFS), proto);
273+
return baseSubMap.lookupConformance(origType->getCanonicalType(), proto);
274274
});
275275
}

lib/AST/RequirementEnvironment.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -85,16 +85,13 @@ RequirementEnvironment::RequirementEnvironment(
8585
// parameters of the requirement into a combined context that provides the
8686
// type parameters of the conformance context and the parameters of the
8787
// requirement.
88-
auto selfType = cast<GenericTypeParamType>(
89-
proto->getSelfInterfaceType()->getCanonicalType());
90-
9188
reqToWitnessThunkSigMap = SubstitutionMap::get(reqSig,
92-
[selfType, substConcreteType, depth, covariantSelf, &ctx]
89+
[substConcreteType, depth, covariantSelf, &ctx]
9390
(SubstitutableType *type) -> Type {
9491
// If the conforming type is a class, the protocol 'Self' maps to
9592
// the class-constrained 'Self'. Otherwise, it maps to the concrete
9693
// type.
97-
if (type->isEqual(selfType)) {
94+
if (type->isEqual(ctx.TheSelfType)) {
9895
if (covariantSelf)
9996
return ctx.TheSelfType;
10097
return substConcreteType;
@@ -114,11 +111,12 @@ RequirementEnvironment::RequirementEnvironment(
114111
}
115112
return substGenericParam;
116113
},
117-
[selfType, substConcreteType, conformance, conformanceDC, covariantSelf, &ctx](
118-
CanType type, Type replacement, ProtocolDecl *proto)
114+
[substConcreteType, conformance, conformanceDC, covariantSelf, &ctx](
115+
InFlightSubstitution &IFS, Type type, ProtocolDecl *proto)
119116
-> ProtocolConformanceRef {
120117
// The protocol 'Self' conforms concretely to the conforming type.
121-
if (type->isEqual(selfType)) {
118+
if (type->isEqual(ctx.TheSelfType)) {
119+
auto replacement = type.subst(IFS);
122120
ASSERT(covariantSelf || replacement->isEqual(substConcreteType));
123121

124122
if (conformance) {
@@ -148,7 +146,7 @@ RequirementEnvironment::RequirementEnvironment(
148146

149147
// All other generic parameters come from the requirement itself
150148
// and conform abstractly.
151-
return MakeAbstractConformanceForGenericType()(type, replacement, proto);
149+
return MakeAbstractConformanceForGenericType()(IFS, type, proto);
152150
});
153151

154152
// If the requirement itself is non-generic, the witness thunk signature

lib/AST/SubstitutionMap.cpp

Lines changed: 33 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -272,61 +272,31 @@ SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const {
272272

273273
auto path = genericSig->getConformancePath(type, proto);
274274

275-
ProtocolConformanceRef conformance;
276-
for (const auto &step : path) {
277-
// For the first step, grab the initial conformance.
278-
if (conformance.isInvalid()) {
279-
if (auto initialConformance = getSignatureConformance(
280-
step.first, step.second)) {
281-
conformance = *initialConformance;
282-
continue;
275+
// For the first step, grab the initial conformance.
276+
auto iter = path.begin();
277+
const auto step = *iter++;
278+
279+
ProtocolConformanceRef conformance =
280+
*getSignatureConformance(step.first, step.second);
281+
282+
// For each remaining step, project an associated conformance.
283+
while (iter != path.end()) {
284+
// FIXME: Remove this hack. It is unsound, because we may not have diagnosed
285+
// anything but still end up with an ErrorType in the AST.
286+
if (conformance.isConcrete()) {
287+
auto concrete = conformance.getConcrete();
288+
auto normal = concrete->getRootNormalConformance();
289+
290+
if (!normal->hasComputedAssociatedConformances()) {
291+
if (proto->getASTContext().evaluator.hasActiveRequest(
292+
ResolveTypeWitnessesRequest{normal})) {
293+
return ProtocolConformanceRef::forInvalid();
294+
}
283295
}
284-
285-
// We couldn't find the initial conformance, fail.
286-
return ProtocolConformanceRef::forInvalid();
287-
}
288-
289-
// If we've hit an abstract conformance, everything from here on out is
290-
// abstract.
291-
// FIXME: This may not always be true, but it holds for now.
292-
if (conformance.isAbstract()) {
293-
// FIXME: Rip this out once we can get a concrete conformance from
294-
// an archetype.
295-
return swift::lookupConformance(type.subst(*this), proto);
296296
}
297297

298-
// For the second step, we're looking into the requirement signature for
299-
// this protocol.
300-
if (conformance.isPack()) {
301-
auto pack = conformance.getPack();
302-
conformance = ProtocolConformanceRef(
303-
pack->getAssociatedConformance(step.first, step.second));
304-
if (conformance.isInvalid())
305-
return conformance;
306-
307-
continue;
308-
}
309-
310-
auto concrete = conformance.getConcrete();
311-
auto normal = concrete->getRootNormalConformance();
312-
313-
// If we haven't set the signature conformances yet, force the issue now.
314-
if (!normal->hasComputedAssociatedConformances()) {
315-
// If we're in the process of checking the type witnesses, fail
316-
// gracefully.
317-
//
318-
// FIXME: This is unsound, because we may not have diagnosed anything but
319-
// still end up with an ErrorType in the AST.
320-
if (proto->getASTContext().evaluator.hasActiveRequest(
321-
ResolveTypeWitnessesRequest{normal})) {
322-
return ProtocolConformanceRef::forInvalid();
323-
}
324-
}
325-
326-
// Get the associated conformance.
327-
conformance = concrete->getAssociatedConformance(step.first, step.second);
328-
if (conformance.isInvalid())
329-
return conformance;
298+
const auto step = *iter++;
299+
conformance = conformance.getAssociatedConformance(step.first, step.second);
330300
}
331301

332302
return conformance;
@@ -473,16 +443,18 @@ Type QueryOverrideSubs::operator()(SubstitutableType *type) const {
473443
}
474444

475445
ProtocolConformanceRef
476-
LookUpConformanceInOverrideSubs::operator()(CanType type,
477-
Type substType,
446+
LookUpConformanceInOverrideSubs::operator()(InFlightSubstitution &IFS,
447+
Type type,
478448
ProtocolDecl *proto) const {
479449
if (type->getRootGenericParam()->getDepth() >= info.BaseDepth)
480-
return ProtocolConformanceRef::forAbstract(substType, proto);
450+
return ProtocolConformanceRef::forAbstract(type.subst(IFS), proto);
481451

482-
if (auto conformance = info.BaseSubMap.lookupConformance(type, proto))
452+
if (auto conformance = info.BaseSubMap.lookupConformance(
453+
type->getCanonicalType(), proto)) {
483454
return conformance;
455+
}
484456

485-
return lookupConformance(substType, proto);
457+
return lookupConformance(type.subst(IFS), proto);
486458
}
487459

488460
SubstitutionMap
@@ -665,8 +637,8 @@ Type OuterSubstitutions::operator()(SubstitutableType *type) const {
665637
}
666638

667639
ProtocolConformanceRef OuterSubstitutions::operator()(
668-
CanType dependentType,
669-
Type conformingReplacementType,
640+
InFlightSubstitution &IFS,
641+
Type dependentType,
670642
ProtocolDecl *conformedProtocol) const {
671643
auto sig = subs.getGenericSignature();
672644
if (!sig->isValidTypeParameter(dependentType) ||
@@ -683,10 +655,10 @@ ProtocolConformanceRef OuterSubstitutions::operator()(
683655
// Once we check for that and handle it properly, the lookupConformance()
684656
// can become a forAbstract().
685657
return swift::lookupConformance(
686-
conformingReplacementType, conformedProtocol);
658+
dependentType.subst(IFS), conformedProtocol);
687659
}
688660

689661
return LookUpConformanceInSubstitutionMap(subs)(
690-
dependentType, conformingReplacementType, conformedProtocol);
662+
IFS, dependentType, conformedProtocol);
691663
}
692664

0 commit comments

Comments
 (0)