Skip to content

Commit eb3f3a1

Browse files
committed
IRGen: Fix crash when normal conformance fixes generic parameter to concrete type
This can probably be handled better elsewhere, but this is reasonable enough for now. Fixes rdar://146123129.
1 parent 26eaf75 commit eb3f3a1

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,16 +1257,16 @@ emitConditionalConformancesBuffer(IRGenFunction &IGF,
12571257
}
12581258

12591259
static llvm::Value *emitWitnessTableAccessorCall(
1260-
IRGenFunction &IGF, const ProtocolConformance *conformance,
1260+
IRGenFunction &IGF, CanType conformingType,
1261+
const ProtocolConformance *conformance,
12611262
llvm::Value **srcMetadataCache) {
12621263
auto conformanceDescriptor =
12631264
IGF.IGM.getAddrOfProtocolConformanceDescriptor(
12641265
conformance->getRootConformance());
12651266

12661267
// Emit the source metadata if we haven't yet.
12671268
if (!*srcMetadataCache) {
1268-
*srcMetadataCache = IGF.emitAbstractTypeMetadataRef(
1269-
conformance->getType()->getCanonicalType());
1269+
*srcMetadataCache = IGF.emitAbstractTypeMetadataRef(conformingType);
12701270
}
12711271

12721272
auto conditionalTables =
@@ -1290,8 +1290,8 @@ static llvm::Value *emitWitnessTableAccessorCall(
12901290
/// given type.
12911291
static llvm::Function *
12921292
getWitnessTableLazyAccessFunction(IRGenModule &IGM,
1293+
CanType conformingType,
12931294
const ProtocolConformance *conformance) {
1294-
auto conformingType = conformance->getType()->getCanonicalType();
12951295
assert(!conformingType->hasArchetype());
12961296

12971297
auto rootConformance = conformance->getRootNormalConformance();
@@ -1315,7 +1315,7 @@ getWitnessTableLazyAccessFunction(IRGenModule &IGM,
13151315
[&](IRGenFunction &IGF, Explosion &params) {
13161316
llvm::Value *conformingMetadataCache = nullptr;
13171317
return MetadataResponse::forComplete(emitWitnessTableAccessorCall(
1318-
IGF, conformance, &conformingMetadataCache));
1318+
IGF, conformingType, conformance, &conformingMetadataCache));
13191319
});
13201320

13211321
return accessor;
@@ -1414,16 +1414,23 @@ class AccessorConformanceInfo : public ConformanceInfo {
14141414

14151415
llvm::Value *getTable(IRGenFunction &IGF,
14161416
llvm::Value **typeMetadataCache) const override {
1417+
auto conformingType = Conformance->getType()->getCanonicalType();
1418+
1419+
if (isa<NormalProtocolConformance>(Conformance)) {
1420+
conformingType = conformingType->getReducedType(
1421+
Conformance->getGenericSignature());
1422+
}
1423+
14171424
// If we're looking up a dependent type, we can't cache the result.
1418-
if (Conformance->getType()->hasArchetype() ||
1419-
Conformance->getType()->hasDynamicSelfType()) {
1420-
return emitWitnessTableAccessorCall(IGF, Conformance,
1425+
if (conformingType->hasArchetype() ||
1426+
conformingType->hasDynamicSelfType()) {
1427+
return emitWitnessTableAccessorCall(IGF, conformingType, Conformance,
14211428
typeMetadataCache);
14221429
}
14231430

14241431
// Otherwise, call a lazy-cache function.
14251432
auto accessor =
1426-
getWitnessTableLazyAccessFunction(IGF.IGM, Conformance);
1433+
getWitnessTableLazyAccessFunction(IGF.IGM, conformingType, Conformance);
14271434
llvm::CallInst *call =
14281435
IGF.Builder.CreateCall(accessor->getFunctionType(), accessor, {});
14291436
call->setCallingConv(IGF.IGM.DefaultCC);

test/IRGen/rdar146123129.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %target-swift-frontend -emit-ir -O -enable-library-evolution %s
2+
// REQUIRES: objc_interop
3+
4+
import Foundation
5+
6+
extension Measurement: Strideable where UnitType == UnitLength {
7+
public func advanced(by n: Double) -> Measurement<UnitLength> {
8+
return Self.init(value: value + n, unit: unit)
9+
}
10+
11+
public func distance(to other: Measurement<UnitLength>) -> Double {
12+
return other.value - value
13+
}
14+
}
15+
public func test(_ gridHalfSizeInLabelSpacingUnits: Measurement<UnitLength>, _ value: Double, _ orientation: Bool) {
16+
let origin = Measurement(value: 0, unit: UnitLength.meters)
17+
18+
@inline(never)
19+
func addLabelMeshForLine(startingAt startPositionMeasurement: Measurement<UnitLength>) {
20+
print(startPositionMeasurement)
21+
}
22+
23+
for startPositionMeasurement in stride(from: origin, through: gridHalfSizeInLabelSpacingUnits, by: value) {
24+
addLabelMeshForLine(startingAt: startPositionMeasurement)
25+
}
26+
}

0 commit comments

Comments
 (0)