Skip to content

Commit 4e71ce5

Browse files
committed
[IRGen] Canonicalize associated type witnesses.
Associated type witnesses were not getting canonicalized with respect to their appropriate generic signatures, causing types to be emitted into the metadata that could not be properly demangled. Be consistent about providing a generic signature for canonicalization. Fixes SR-11642 / rdar://problem/56466693.
1 parent 942aeca commit 4e71ce5

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
@@ -1294,7 +1294,10 @@ class AccessorConformanceInfo : public ConformanceInfo {
12941294
auto associate =
12951295
Conformance.getTypeWitness(requirement.getAssociation());
12961296
llvm::Constant *witness =
1297-
IGM.getAssociatedTypeWitness(associate, /*inProtocolContext=*/false);
1297+
IGM.getAssociatedTypeWitness(
1298+
associate,
1299+
Conformance.getDeclContext()->getGenericSignatureOfContext(),
1300+
/*inProtocolContext=*/false);
12981301
Table.addBitCast(witness, IGM.Int8PtrTy);
12991302
}
13001303

@@ -1427,6 +1430,7 @@ void WitnessTableBuilder::build() {
14271430
}
14281431

14291432
llvm::Constant *IRGenModule::getAssociatedTypeWitness(Type type,
1433+
GenericSignature sig,
14301434
bool inProtocolContext) {
14311435
// FIXME: If we can directly reference constant type metadata, do so.
14321436

@@ -1435,7 +1439,7 @@ llvm::Constant *IRGenModule::getAssociatedTypeWitness(Type type,
14351439
auto role = inProtocolContext
14361440
? MangledTypeRefRole::DefaultAssociatedTypeWitness
14371441
: MangledTypeRefRole::Metadata;
1438-
auto typeRef = getTypeRef(type, /*generic signature*/nullptr, role).first;
1442+
auto typeRef = getTypeRef(type, sig, role).first;
14391443

14401444
// Set the low bit to indicate that this is a mangled name.
14411445
auto witness = llvm::ConstantExpr::getPtrToInt(typeRef, IntPtrTy);
@@ -1604,7 +1608,10 @@ void WitnessTableBuilder::collectResilientWitnesses(
16041608
auto associate = conformance.getTypeWitness(assocType);
16051609

16061610
llvm::Constant *witness =
1607-
IGM.getAssociatedTypeWitness(associate, /*inProtocolContext=*/false);
1611+
IGM.getAssociatedTypeWitness(
1612+
associate,
1613+
conformance.getDeclContext()->getGenericSignatureOfContext(),
1614+
/*inProtocolContext=*/false);
16081615
resilientWitnesses.push_back(witness);
16091616
continue;
16101617
}

lib/IRGen/IRGenModule.h

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

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

11271128
void emitAssociatedTypeMetadataRecord(const RootProtocolConformance *C);
11281129
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)