Skip to content

Commit d59c23f

Browse files
authored
Merge pull request #28869 from DougGregor/assoc-type-witness-canon
[IRGen] Canonicalize associated type witnesses.
2 parents 36f467c + 4e71ce5 commit d59c23f

File tree

4 files changed

+45
-6
lines changed

4 files changed

+45
-6
lines changed

lib/IRGen/GenMeta.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,7 @@ namespace {
824824
auto witness =
825825
entry.getAssociatedTypeWitness().Witness->mapTypeOutOfContext();
826826
return IGM.getAssociatedTypeWitness(witness,
827+
Proto->getGenericSignature(),
827828
/*inProtocolContext=*/true);
828829
}
829830

@@ -1593,8 +1594,7 @@ namespace {
15931594
// TargetRelativeDirectPointer<Runtime, const char> SuperclassType;
15941595
if (auto superclassType = getType()->getSuperclass()) {
15951596
GenericSignature genericSig = getType()->getGenericSignature();
1596-
B.addRelativeAddress(IGM.getTypeRef(superclassType->getCanonicalType(),
1597-
genericSig,
1597+
B.addRelativeAddress(IGM.getTypeRef(superclassType, genericSig,
15981598
MangledTypeRefRole::Metadata)
15991599
.first);
16001600
} else {

lib/IRGen/GenProto.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,7 +1303,10 @@ class AccessorConformanceInfo : public ConformanceInfo {
13031303
auto associate =
13041304
Conformance.getTypeWitness(requirement.getAssociation());
13051305
llvm::Constant *witness =
1306-
IGM.getAssociatedTypeWitness(associate, /*inProtocolContext=*/false);
1306+
IGM.getAssociatedTypeWitness(
1307+
associate,
1308+
Conformance.getDeclContext()->getGenericSignatureOfContext(),
1309+
/*inProtocolContext=*/false);
13071310
Table.addBitCast(witness, IGM.Int8PtrTy);
13081311
}
13091312

@@ -1436,6 +1439,7 @@ void WitnessTableBuilder::build() {
14361439
}
14371440

14381441
llvm::Constant *IRGenModule::getAssociatedTypeWitness(Type type,
1442+
GenericSignature sig,
14391443
bool inProtocolContext) {
14401444
// FIXME: If we can directly reference constant type metadata, do so.
14411445

@@ -1444,7 +1448,7 @@ llvm::Constant *IRGenModule::getAssociatedTypeWitness(Type type,
14441448
auto role = inProtocolContext
14451449
? MangledTypeRefRole::DefaultAssociatedTypeWitness
14461450
: MangledTypeRefRole::Metadata;
1447-
auto typeRef = getTypeRef(type, /*generic signature*/nullptr, role).first;
1451+
auto typeRef = getTypeRef(type, sig, role).first;
14481452

14491453
// Set the low bit to indicate that this is a mangled name.
14501454
auto witness = llvm::ConstantExpr::getPtrToInt(typeRef, IntPtrTy);
@@ -1613,7 +1617,10 @@ void WitnessTableBuilder::collectResilientWitnesses(
16131617
auto associate = conformance.getTypeWitness(assocType);
16141618

16151619
llvm::Constant *witness =
1616-
IGM.getAssociatedTypeWitness(associate, /*inProtocolContext=*/false);
1620+
IGM.getAssociatedTypeWitness(
1621+
associate,
1622+
conformance.getDeclContext()->getGenericSignatureOfContext(),
1623+
/*inProtocolContext=*/false);
16171624
resilientWitnesses.push_back(witness);
16181625
continue;
16191626
}

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,8 @@ class IRGenModule {
11231123
CanGenericSignature genericSig);
11241124

11251125
/// Produce an associated type witness that refers to the given type.
1126-
llvm::Constant *getAssociatedTypeWitness(Type type, bool inProtocolContext);
1126+
llvm::Constant *getAssociatedTypeWitness(Type type, GenericSignature sig,
1127+
bool inProtocolContext);
11271128

11281129
void emitAssociatedTypeMetadataRecord(const RootProtocolConformance *C);
11291130
void emitFieldDescriptor(const NominalTypeDecl *Decl);

test/IRGen/associated_type_witness.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,37 @@ struct UsesVoid : HasSimpleAssoc {
133133
typealias Assoc = ()
134134
}
135135

136+
// SR-11642: Failure to canonicalize type in associated type witness.
137+
struct Validator<T> {
138+
let validatorFailureType: Any.Type
139+
}
140+
141+
142+
protocol ValidatorType {
143+
associatedtype Data
144+
associatedtype Failure
145+
func validator() -> Validator<Data>
146+
}
147+
148+
149+
extension ValidatorType {
150+
func validator() -> Validator<Data> {
151+
.init(validatorFailureType: Failure.self)
152+
}
153+
}
154+
155+
156+
// MARK: Failing example
157+
extension Validator where T == String {
158+
// GLOBAL: @"symbolic _____ySS__G 23associated_type_witness9ValidatorVAASSRszlE1VV7FailureV"
159+
struct V: ValidatorType {
160+
typealias Data = T // or String
161+
162+
struct Failure {}
163+
}
164+
}
165+
166+
136167
// Protocol conformance descriptor for Computed : Assocked.
137168
// GLOBAL-LABEL: @"$s23associated_type_witness8ComputedVyxq_GAA8AssockedAAMc" = hidden constant
138169
// GLOBAL-SAME: i16 4,

0 commit comments

Comments
 (0)