Skip to content

Commit 0f18125

Browse files
committed
Runtime: Fix dynamic casts of variadic types that conditionally conform
1 parent e765464 commit 0f18125

File tree

4 files changed

+25
-4
lines changed

4 files changed

+25
-4
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2850,16 +2850,20 @@ void SubstGenericParametersFromMetadata::setup() const {
28502850
assert(baseContext);
28512851
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
28522852
numKeyGenericParameters = buildDescriptorPath(baseContext, demangler);
2853+
if (auto *genericCtx = baseContext->getGenericContext())
2854+
numShapeClasses = genericCtx->getGenericPackShapeHeader().NumShapeClasses;
28532855
return;
28542856
}
28552857
case SourceKind::Environment: {
28562858
assert(environment);
28572859
numKeyGenericParameters = buildEnvironmentPath(environment);
2860+
// FIXME: Variadic generics
28582861
return;
28592862
}
28602863
case SourceKind::Shape: {
28612864
assert(shape);
28622865
numKeyGenericParameters = buildShapePath(shape);
2866+
// FIXME: Variadic generics
28632867
return;
28642868
}
28652869
}
@@ -2883,7 +2887,7 @@ SubstGenericParametersFromMetadata::getMetadata(
28832887
return MetadataOrPack();
28842888

28852889
// Compute the flat index.
2886-
unsigned flatIndex = pathElement.numKeyGenericParamsInParent;
2890+
unsigned flatIndex = pathElement.numKeyGenericParamsInParent + numShapeClasses;
28872891
if (pathElement.hasNonKeyGenericParams > 0) {
28882892
// We have non-key generic parameters at this level, so the index needs to
28892893
// be checked more carefully.
@@ -2912,7 +2916,8 @@ SubstGenericParametersFromMetadata::getWitnessTable(const Metadata *type,
29122916
// On first access, compute the descriptor path.
29132917
setup();
29142918

2915-
return (const WitnessTable *)genericArgs[index + numKeyGenericParameters];
2919+
return (const WitnessTable *)genericArgs[
2920+
index + numKeyGenericParameters + numShapeClasses];
29162921
}
29172922

29182923
MetadataOrPack SubstGenericParametersFromWrittenArgs::getMetadata(

stdlib/public/runtime/Private.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ class TypeInfo {
395395
/// The number of key generic parameters.
396396
mutable unsigned numKeyGenericParameters = 0;
397397

398+
/// The number of pack shape classes.
399+
mutable unsigned numShapeClasses = 0;
400+
398401
/// Builds the descriptor path.
399402
///
400403
/// \returns a pair containing the number of key generic parameters in

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,7 @@ ProtocolConformanceDescriptor::getWitnessTable(const Metadata *type) const {
332332
auto error = _checkGenericRequirements(
333333
getConditionalRequirements(), conditionalArgs,
334334
[&substitutions](unsigned depth, unsigned index) {
335-
// FIXME: Variadic generics
336-
return substitutions.getMetadata(depth, index).getMetadataOrNull();
335+
return substitutions.getMetadata(depth, index).Ptr;
337336
},
338337
[&substitutions](const Metadata *type, unsigned index) {
339338
return substitutions.getWitnessTable(type, index);

test/Interpreter/variadic_generic_conditional_conformances.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,18 @@ conformances.test("conditional") {
4545
expectEqual(["Int", "String"], callFoobar(G<Int, String>()))
4646
}
4747

48+
func cast<T, U>(_ value: T, to: U.Type) -> Bool {
49+
return value is U
50+
}
51+
52+
conformances.test("cast") {
53+
expectEqual(true, cast(G< >(), to: (any P).self))
54+
expectEqual(true, cast(G<Int>(), to: (any P).self))
55+
expectEqual(true, cast(G<Int, String>(), to: (any P).self))
56+
57+
expectEqual(false, cast(G<Bool>(), to: (any P).self))
58+
expectEqual(false, cast(G<Int, Bool>(), to: (any P).self))
59+
expectEqual(false, cast(G<Bool, Int>(), to: (any P).self))
60+
}
61+
4862
runAllTests()

0 commit comments

Comments
 (0)