Merge pull request #12120 from slavapestov/enum-sil-test-watchos
IRGen: Fix enum.sil test on watchos simulator
diff --git a/lib/IRGen/Fulfillment.cpp b/lib/IRGen/Fulfillment.cpp
index b52de85..739b4f5 100644
--- a/lib/IRGen/Fulfillment.cpp
+++ b/lib/IRGen/Fulfillment.cpp
@@ -70,12 +70,12 @@
case TypeKind::Tuple:
return cast<TupleType>(type)->getNumElements() == 0;
- // Nominal types might have parents.
+ // Nominal types might have generic parents.
case TypeKind::Class:
case TypeKind::Enum:
case TypeKind::Protocol:
case TypeKind::Struct:
- return !cast<NominalType>(type)->getParent();
+ return !cast<NominalType>(type)->getDecl()->isGenericContext();
// Bound generic types have type arguments.
case TypeKind::BoundGenericClass:
@@ -125,6 +125,13 @@
return hadFulfillment;
}
+ if (keys.isInterestingType(type)) {
+ if (auto superclassTy = keys.getSuperclassBound(type)) {
+ return searchNominalTypeMetadata(IGM, superclassTy, source,
+ std::move(path), keys);
+ }
+ }
+
// Inexact metadata will be a problem if we ever try to use this
// to remember that we already have the metadata for something.
if (isa<NominalType>(type) || isa<BoundGenericType>(type)) {
@@ -289,21 +296,6 @@
}
}
-bool FulfillmentMap::Everything::isInterestingType(CanType type) const {
- return true;
-}
-bool FulfillmentMap::Everything::hasInterestingType(CanType type) const {
- return true;
-}
-bool FulfillmentMap::Everything
- ::hasLimitedInterestingConformances(CanType type) const {
- return false;
-}
-GenericSignature::ConformsToArray
-FulfillmentMap::Everything::getInterestingConformances(CanType type) const{
- return {};
-}
-
void FulfillmentMap::dump() const {
auto &out = llvm::errs();
for (auto &entry : Fulfillments) {
diff --git a/lib/IRGen/Fulfillment.h b/lib/IRGen/Fulfillment.h
index 858e1d5..65737b6 100644
--- a/lib/IRGen/Fulfillment.h
+++ b/lib/IRGen/Fulfillment.h
@@ -66,17 +66,10 @@
virtual GenericSignature::ConformsToArray
getInterestingConformances(CanType type) const = 0;
- virtual ~InterestingKeysCallback() = default;
- };
+ /// Return the limited interesting conformances for an interesting type.
+ virtual CanType getSuperclassBound(CanType type) const = 0;
- /// An implementation of InterestingKeysCallback that returns everything
- /// fulfillable.
- struct Everything : InterestingKeysCallback {
- bool isInterestingType(CanType type) const override;
- bool hasInterestingType(CanType type) const override;
- bool hasLimitedInterestingConformances(CanType type) const override;
- GenericSignature::ConformsToArray
- getInterestingConformances(CanType type) const override;
+ virtual ~InterestingKeysCallback() = default;
};
FulfillmentMap() = default;
diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp
index 05cc66a..3982e34 100644
--- a/lib/IRGen/GenProto.cpp
+++ b/lib/IRGen/GenProto.cpp
@@ -95,6 +95,12 @@
return Generics->getConformsTo(t, M);
}
+ CanType getSuperclassBound(Type t) {
+ if (auto superclassTy = Generics->getSuperclassBound(t, M))
+ return superclassTy->getCanonicalType();
+ return CanType();
+ }
+
public:
PolymorphicConvention(IRGenModule &IGM, CanSILFunctionType fnType);
@@ -291,6 +297,9 @@
getInterestingConformances(CanType type) const override {
return Self.getConformsTo(type);
}
+ CanType getSuperclassBound(CanType type) const override {
+ return Self.getSuperclassBound(type);
+ }
} callbacks(*this);
return Fulfillments.searchTypeMetadata(IGM, type, isExact, sourceIndex,
std::move(path), callbacks);
@@ -367,6 +376,15 @@
return;
}
+ if (isa<GenericTypeParamType>(type)) {
+ if (auto superclassTy = getSuperclassBound(type)) {
+ considerNewTypeSource(MetadataSource::Kind::ClassPointer,
+ paramIndex, superclassTy, IsInexact);
+ return;
+
+ }
+ }
+
// Thick metatypes are sources of metadata.
if (auto metatypeTy = dyn_cast<MetatypeType>(type)) {
if (metatypeTy->getRepresentation() != MetatypeRepresentation::Thick)
@@ -1284,6 +1302,11 @@
getInterestingConformances(CanType type) const override {
llvm_unreachable("no limits");
}
+ CanType getSuperclassBound(CanType type) const override {
+ if (auto superclassTy = cast<ArchetypeType>(type)->getSuperclass())
+ return superclassTy->getCanonicalType();
+ return CanType();
+ }
} callback;
Fulfillments->searchTypeMetadata(IGM, ConcreteType, IsExact,
/*sourceIndex*/ 0, MetadataPath(),
@@ -2023,7 +2046,10 @@
case Component::Kind::NominalTypeArgument:
case Component::Kind::NominalTypeArgumentConformance: {
assert(sourceKey.Kind == LocalTypeDataKind::forTypeMetadata());
- auto *nominal = sourceKey.Type.getAnyNominal();
+ auto type = sourceKey.Type;
+ if (auto archetypeTy = dyn_cast<ArchetypeType>(type))
+ type = archetypeTy->getSuperclass()->getCanonicalType();
+ auto *nominal = type.getAnyNominal();
auto reqtIndex = component.getPrimaryIndex();
GenericTypeRequirements requirements(IGF.IGM, nominal);
diff --git a/lib/IRGen/LocalTypeData.cpp b/lib/IRGen/LocalTypeData.cpp
index 3deddfb..fe2fc05 100644
--- a/lib/IRGen/LocalTypeData.cpp
+++ b/lib/IRGen/LocalTypeData.cpp
@@ -254,12 +254,34 @@
CanType type,
IsExact_t isExact,
llvm::Value *metadata) {
+ struct Callback : FulfillmentMap::InterestingKeysCallback {
+ bool isInterestingType(CanType type) const override {
+ return true;
+ }
+ bool hasInterestingType(CanType type) const override {
+ return true;
+ }
+ bool hasLimitedInterestingConformances(CanType type) const override {
+ return false;
+ }
+ GenericSignature::ConformsToArray
+ getInterestingConformances(CanType type) const override {
+ llvm_unreachable("no limits");
+ }
+ CanType getSuperclassBound(CanType type) const override {
+ if (auto arch = dyn_cast<ArchetypeType>(type))
+ if (auto superclassTy = arch->getSuperclass())
+ return superclassTy->getCanonicalType();
+ return CanType();
+ }
+ } callbacks;
+
// Look for anything at all that's fulfilled by this. If we don't find
// anything, stop.
FulfillmentMap fulfillments;
if (!fulfillments.searchTypeMetadata(IGF.IGM, type, isExact,
/*source*/ 0, MetadataPath(),
- FulfillmentMap::Everything())) {
+ callbacks)) {
return;
}
diff --git a/lib/SIL/SILFunctionType.cpp b/lib/SIL/SILFunctionType.cpp
index 4a51087..dbb400d 100644
--- a/lib/SIL/SILFunctionType.cpp
+++ b/lib/SIL/SILFunctionType.cpp
@@ -100,6 +100,9 @@
assert(getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod);
auto selfTy = getSelfInstanceType();
if (auto paramTy = dyn_cast<GenericTypeParamType>(selfTy)) {
+ auto superclass = GenericSig->getSuperclassBound(paramTy, M);
+ if (superclass)
+ return nullptr;
assert(paramTy->getDepth() == 0 && paramTy->getIndex() == 0);
auto protos = GenericSig->getConformsTo(paramTy, M);
assert(protos.size() == 1);
diff --git a/test/IRGen/class_bounded_generics.swift b/test/IRGen/class_bounded_generics.swift
index 184f8ae..573a13b 100644
--- a/test/IRGen/class_bounded_generics.swift
+++ b/test/IRGen/class_bounded_generics.swift
@@ -1,4 +1,4 @@
-// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -emit-ir -primary-file %s -disable-objc-attr-requires-foundation-module | %FileCheck %s
+// RUN: %target-swift-frontend -emit-ir -primary-file %s -disable-objc-attr-requires-foundation-module | %FileCheck %s
// REQUIRES: CPU=x86_64
// XFAIL: linux
@@ -9,7 +9,7 @@
protocol ClassBound2 : class {
func classBoundMethod2()
}
-protocol ClassBoundBinary : class, ClassBound {
+protocol ClassBoundBinary : ClassBound {
func classBoundBinaryMethod(_ x: Self)
}
@objc protocol ObjCClassBound {
@@ -214,7 +214,7 @@
}
// CHECK-LABEL: define hidden swiftcc { i64, %objc_object*, i64 } @_T022class_bounded_generics0A28_generic_field_struct_fields{{[_0-9a-zA-Z]*}}F(i64, %objc_object*, i64, %swift.type* %T, i8** %T.ClassBound)
-func class_generic_field_struct_fields<T : ClassBound>
+func class_generic_field_struct_fields<T>
(_ x:ClassGenericFieldStruct<T>) -> (Int, T, Int) {
return (x.x, x.y, x.z)
}
@@ -226,7 +226,7 @@
}
// CHECK-LABEL: define hidden swiftcc { i64, %objc_object*, i64 } @_T022class_bounded_generics0a15_generic_field_A7_fields{{[_0-9a-zA-Z]*}}F(%T22class_bounded_generics017ClassGenericFieldD0C*)
-func class_generic_field_class_fields<T : ClassBound>
+func class_generic_field_class_fields<T>
(_ x:ClassGenericFieldClass<T>) -> (Int, T, Int) {
return (x.x, x.y, x.z)
// CHECK: getelementptr inbounds %T22class_bounded_generics017ClassGenericFieldD0C, %T22class_bounded_generics017ClassGenericFieldD0C* %0, i32 0, i32 1
@@ -273,3 +273,36 @@
s = S.init()
}
}
+
+// CHECK-LABEL: define hidden swiftcc void @_T022class_bounded_generics14takes_metatypeyxmlF(%swift.type*, %swift.type* %T)
+func takes_metatype<T>(_: T.Type) {}
+
+// CHECK-LABEL: define hidden swiftcc void @_T022class_bounded_generics023archetype_with_generic_A11_constraintyx1t_tAA1ACyq_GRbzr0_lF(%T22class_bounded_generics1AC.2*, %swift.type* %T)
+// CHECK: [[ISA_ADDR:%.*]] = bitcast %T22class_bounded_generics1AC.2* %0 to %swift.type**
+// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
+// CHECK-NEXT: call swiftcc void @_T022class_bounded_generics14takes_metatypeyxmlF(%swift.type* %T, %swift.type* %T)
+// CHECK-NEXT: [[ISA_PTR:%.*]] = bitcast %swift.type* [[ISA]] to %swift.type**
+// CHECK-NEXT: [[U_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[ISA_PTR]], i64 10
+// CHECK-NEXT: [[U:%.*]] = load %swift.type*, %swift.type** [[U_ADDR]]
+// CHECK-NEXT: call swiftcc void @_T022class_bounded_generics14takes_metatypeyxmlF(%swift.type* %U, %swift.type* %U)
+// CHECK: ret void
+
+func archetype_with_generic_class_constraint<T, U>(t: T) where T : A<U> {
+ takes_metatype(T.self)
+ takes_metatype(U.self)
+}
+
+// CHECK-LABEL: define hidden swiftcc void @_T022class_bounded_generics029calls_archetype_with_generic_A11_constraintyAA1ACyxG1a_tlF(%T22class_bounded_generics1AC*) #0 {
+// CHECK: [[ISA_ADDR:%.*]] = getelementptr inbounds %T22class_bounded_generics1AC, %T22class_bounded_generics1AC* %0, i32 0, i32 0, i32 0
+// CHECK-NEXT: [[ISA:%.*]] = load %swift.type*, %swift.type** [[ISA_ADDR]]
+// CHECK: [[SELF:%.*]] = bitcast %T22class_bounded_generics1AC* %0 to %T22class_bounded_generics1AC.2*
+// CHECK-NEXT: [[ISA_PTR:%.*]] = bitcast %swift.type* [[ISA]] to %swift.type**
+// CHECK-NEXT: [[T_ADDR:%.*]] = getelementptr inbounds %swift.type*, %swift.type** [[ISA_PTR]], i64 10
+// CHECK-NEXT: [[T:%.*]] = load %swift.type*, %swift.type** [[T_ADDR]]
+// CHECK-NEXT: [[A_OF_T:%.*]] = call %swift.type* @_T022class_bounded_generics1ACMa(%swift.type* [[T]])
+// CHECK-NEXT: call swiftcc void @_T022class_bounded_generics023archetype_with_generic_A11_constraintyx1t_tAA1ACyq_GRbzr0_lF(%T22class_bounded_generics1AC.2* [[SELF]], %swift.type* [[A_OF_T]])
+// CHECK: ret void
+
+func calls_archetype_with_generic_class_constraint<T>(a: A<T>) {
+ archetype_with_generic_class_constraint(t: a)
+}