Skip to content

Commit 22382f7

Browse files
committed
Reimplement associated conformance IRGen using Doug's conformance
access path work. Having done so, simplify archetype TypeInfos by removing a now- unnecessary layer of abstraction.
1 parent 5b4c2cf commit 22382f7

File tree

9 files changed

+319
-313
lines changed

9 files changed

+319
-313
lines changed

include/swift/AST/ProtocolConformance.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,18 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
229229
/// Retrieve the complete set of protocol conformances for directly inherited
230230
/// protocols.
231231
const InheritedConformanceMap &getInheritedConformances() const;
232+
233+
/// Given a dependent type expressed in terms of the self parameter,
234+
/// map it into the context of this conformance.
235+
Type getAssociatedType(Type assocType,
236+
LazyResolver *resolver = nullptr) const;
237+
238+
/// Given that the requirement signature of the protocol directly states
239+
/// that the given dependent type must conform to the given protocol,
240+
/// return its associated conformance.
241+
ProtocolConformanceRef
242+
getAssociatedConformance(Type assocType, ProtocolDecl *protocol,
243+
LazyResolver *resolver = nullptr) const;
232244

233245
/// Get the generic parameters open on the conforming type.
234246
GenericEnvironment *getGenericEnvironment() const;
@@ -441,11 +453,6 @@ class NormalProtocolConformance : public ProtocolConformance,
441453
const Substitution &substitution,
442454
TypeDecl *typeDecl) const;
443455

444-
/// Given a dependent type expressed in terms of the self parameter,
445-
/// map it into the context of this conformance.
446-
Type getAssociatedType(Type assocType,
447-
LazyResolver *resolver = nullptr) const;
448-
449456
/// Given that the requirement signature of the protocol directly states
450457
/// that the given dependent type must conform to the given protocol,
451458
/// return its associated conformance.
@@ -611,6 +618,13 @@ class SpecializedProtocolConformance : public ProtocolConformance,
611618
return GenericConformance->getInheritedConformances();
612619
}
613620

621+
/// Given that the requirement signature of the protocol directly states
622+
/// that the given dependent type must conform to the given protocol,
623+
/// return its associated conformance.
624+
ProtocolConformanceRef
625+
getAssociatedConformance(Type assocType, ProtocolDecl *protocol,
626+
LazyResolver *resolver = nullptr) const;
627+
614628
/// Determine whether the witness for the given requirement
615629
/// is either the default definition or was otherwise deduced.
616630
bool usesDefaultDefinition(AssociatedTypeDecl *requirement) const {
@@ -709,6 +723,13 @@ class InheritedProtocolConformance : public ProtocolConformance,
709723
return InheritedConformance->getWitness(requirement, resolver);
710724
}
711725

726+
/// Given that the requirement signature of the protocol directly states
727+
/// that the given dependent type must conform to the given protocol,
728+
/// return its associated conformance.
729+
ProtocolConformanceRef
730+
getAssociatedConformance(Type assocType, ProtocolDecl *protocol,
731+
LazyResolver *resolver = nullptr) const;
732+
712733
/// Retrieve the protocol conformances directly-inherited protocols.
713734
const InheritedConformanceMap &getInheritedConformances() const {
714735
return InheritedConformance->getInheritedConformances();

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ class ProtocolConformanceRef {
9696
TypeSubstitutionFn subs,
9797
LookupConformanceFn conformances) const;
9898

99+
/// Given a dependent type (expressed in terms of this conformance's
100+
/// protocol), follow it from the conforming type.
101+
Type getAssociatedType(Type origType, Type dependentType,
102+
LazyResolver *resolver = nullptr) const;
103+
104+
/// Given a dependent type (expressed in terms of this conformance's
105+
/// protocol) and conformance, follow it from the conforming type.
106+
ProtocolConformanceRef
107+
getAssociatedConformance(Type origType, Type dependentType,
108+
ProtocolDecl *requirement,
109+
LazyResolver *resolver = nullptr) const;
110+
99111
void dump() const;
100112
void dump(llvm::raw_ostream &out, unsigned indent = 0) const;
101113

lib/AST/ProtocolConformance.cpp

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -397,13 +397,22 @@ void NormalProtocolConformance::setTypeWitness(
397397
TypeWitnesses[assocType] = std::make_pair(substitution, typeDecl);
398398
}
399399

400-
Type NormalProtocolConformance::getAssociatedType(Type assocType,
401-
LazyResolver *resolver) const {
400+
Type ProtocolConformance::getAssociatedType(Type assocType,
401+
LazyResolver *resolver) const {
402402
assert(assocType->isTypeParameter() &&
403403
"associated type must be a type parameter");
404404

405+
ProtocolConformanceRef ref(const_cast<ProtocolConformance*>(this));
406+
return ref.getAssociatedType(getType(), assocType, resolver);
407+
}
408+
409+
Type ProtocolConformanceRef::getAssociatedType(Type conformingType,
410+
Type assocType,
411+
LazyResolver *resolver) const {
412+
assert(!isConcrete() || getConcrete()->getType()->isEqual(conformingType));
413+
405414
auto type = assocType->getCanonicalType();
406-
auto proto = getProtocol();
415+
auto proto = getRequirement();
407416

408417
#if false
409418
// Fast path for generic parameters.
@@ -421,13 +430,43 @@ Type NormalProtocolConformance::getAssociatedType(Type assocType,
421430
#endif
422431

423432
// General case: consult the substitution map.
424-
auto self = const_cast<NormalProtocolConformance *>(this);
425433
auto substMap =
426-
SubstitutionMap::getProtocolSubstitutions(proto, getType(),
427-
ProtocolConformanceRef(self));
434+
SubstitutionMap::getProtocolSubstitutions(proto, conformingType, *this);
428435
return type.subst(substMap);
429436
}
430437

438+
ProtocolConformanceRef
439+
ProtocolConformanceRef::getAssociatedConformance(Type conformingType,
440+
Type assocType,
441+
ProtocolDecl *protocol,
442+
LazyResolver *resolver) const {
443+
// If this is a concrete conformance, look up the associated conformance.
444+
if (isConcrete()) {
445+
auto conformance = getConcrete();
446+
assert(conformance->getType()->isEqual(conformingType));
447+
return conformance->getAssociatedConformance(assocType, protocol, resolver);
448+
}
449+
450+
// Otherwise, apply the substitution {self -> conformingType}
451+
// to the abstract conformance requirement laid upon the dependent type
452+
// by the protocol.
453+
auto subMap =
454+
SubstitutionMap::getProtocolSubstitutions(getRequirement(),
455+
conformingType, *this);
456+
auto abstractConf = ProtocolConformanceRef(protocol);
457+
return abstractConf.subst(assocType,
458+
QuerySubstitutionMap{subMap},
459+
LookUpConformanceInSubstitutionMap(subMap));
460+
}
461+
462+
ProtocolConformanceRef
463+
ProtocolConformance::getAssociatedConformance(Type assocType,
464+
ProtocolDecl *protocol,
465+
LazyResolver *resolver) const {
466+
CONFORMANCE_SUBCLASS_DISPATCH(getAssociatedConformance,
467+
(assocType, protocol, resolver))
468+
}
469+
431470
ProtocolConformanceRef
432471
NormalProtocolConformance::getAssociatedConformance(Type assocType,
433472
ProtocolDecl *protocol,
@@ -582,6 +621,35 @@ SpecializedProtocolConformance::getWitness(ValueDecl *requirement,
582621
return GenericConformance->getWitness(requirement, resolver);
583622
}
584623

624+
ProtocolConformanceRef
625+
SpecializedProtocolConformance::getAssociatedConformance(Type assocType,
626+
ProtocolDecl *protocol,
627+
LazyResolver *resolver) const {
628+
ProtocolConformanceRef conformance =
629+
GenericConformance->getAssociatedConformance(assocType, protocol, resolver);
630+
631+
auto genericEnv = GenericConformance->getGenericEnvironment();
632+
auto subMap = genericEnv->getSubstitutionMap(GenericSubstitutions);
633+
634+
Type origType =
635+
(conformance.isConcrete()
636+
? conformance.getConcrete()->getType()
637+
: GenericConformance->getAssociatedType(assocType, resolver));
638+
639+
return conformance.subst(origType,
640+
QuerySubstitutionMap{subMap},
641+
LookUpConformanceInSubstitutionMap(subMap));
642+
}
643+
644+
ProtocolConformanceRef
645+
InheritedProtocolConformance::getAssociatedConformance(Type assocType,
646+
ProtocolDecl *protocol,
647+
LazyResolver *resolver) const {
648+
// FIXME: Substitute!
649+
return InheritedConformance->getAssociatedConformance(assocType, protocol,
650+
resolver);
651+
}
652+
585653
const NormalProtocolConformance *
586654
ProtocolConformance::getRootNormalConformance() const {
587655
const ProtocolConformance *C = this;

0 commit comments

Comments
 (0)