Skip to content

Commit 3052e36

Browse files
committed
Runtime: Fix dynamic casts of variadic types that conditionally conform
1 parent d1cb930 commit 3052e36

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
@@ -2855,16 +2855,20 @@ void SubstGenericParametersFromMetadata::setup() const {
28552855
assert(baseContext);
28562856
DemanglerForRuntimeTypeResolution<StackAllocatedDemangler<2048>> demangler;
28572857
numKeyGenericParameters = buildDescriptorPath(baseContext, demangler);
2858+
if (auto *genericCtx = baseContext->getGenericContext())
2859+
numShapeClasses = genericCtx->getGenericPackShapeHeader().NumShapeClasses;
28582860
return;
28592861
}
28602862
case SourceKind::Environment: {
28612863
assert(environment);
28622864
numKeyGenericParameters = buildEnvironmentPath(environment);
2865+
// FIXME: Variadic generics
28632866
return;
28642867
}
28652868
case SourceKind::Shape: {
28662869
assert(shape);
28672870
numKeyGenericParameters = buildShapePath(shape);
2871+
// FIXME: Variadic generics
28682872
return;
28692873
}
28702874
}
@@ -2888,7 +2892,7 @@ SubstGenericParametersFromMetadata::getMetadata(
28882892
return MetadataOrPack();
28892893

28902894
// Compute the flat index.
2891-
unsigned flatIndex = pathElement.numKeyGenericParamsInParent;
2895+
unsigned flatIndex = pathElement.numKeyGenericParamsInParent + numShapeClasses;
28922896
if (pathElement.hasNonKeyGenericParams > 0) {
28932897
// We have non-key generic parameters at this level, so the index needs to
28942898
// be checked more carefully.
@@ -2917,7 +2921,8 @@ SubstGenericParametersFromMetadata::getWitnessTable(const Metadata *type,
29172921
// On first access, compute the descriptor path.
29182922
setup();
29192923

2920-
return (const WitnessTable *)genericArgs[index + numKeyGenericParameters];
2924+
return (const WitnessTable *)genericArgs[
2925+
index + numKeyGenericParameters + numShapeClasses];
29212926
}
29222927

29232928
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
@@ -333,8 +333,7 @@ ProtocolConformanceDescriptor::getWitnessTable(const Metadata *type) const {
333333
auto error = _checkGenericRequirements(
334334
getConditionalRequirements(), conditionalArgs,
335335
[&substitutions](unsigned depth, unsigned index) {
336-
// FIXME: Variadic generics
337-
return substitutions.getMetadata(depth, index).getMetadataOrNull();
336+
return substitutions.getMetadata(depth, index).Ptr;
338337
},
339338
[&substitutions](const Metadata *type, unsigned index) {
340339
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)