Skip to content

Commit 388dee5

Browse files
committed
[IRGen] Functions with the ObjCMethod convention are not polymorphic.
...even if the 'self' type is generic. Additionally, Objective-C generic types cannot be used as a source of type metadata, because Objective-C generics are erased at runtime by default. (This may need to change.) With these two changes, we now pass type metadata explicitly when we need to, and /don't/ try to pass it to Objective-C methods that would have needed it if they were Swift methods.
1 parent b7dddf1 commit 388dee5

File tree

4 files changed

+17
-15
lines changed

4 files changed

+17
-15
lines changed

lib/IRGen/Fulfillment.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,9 @@ bool FulfillmentMap::searchBoundGenericTypeMetadata(ModuleDecl &M,
230230
unsigned source,
231231
MetadataPath &&path,
232232
const InterestingKeysCallback &keys) {
233+
if (type->getDecl()->hasClangNode())
234+
return false;
235+
233236
auto params = type->getDecl()->getGenericParams()->getAllArchetypes();
234237
auto substitutions = type->getSubstitutions(&M, nullptr);
235238
assert(params.size() >= substitutions.size() &&

lib/IRGen/GenProto.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -1283,9 +1283,13 @@ bool irgen::hasPolymorphicParameters(CanSILFunctionType ty) {
12831283
case SILFunctionTypeRepresentation::Thick:
12841284
case SILFunctionTypeRepresentation::Thin:
12851285
case SILFunctionTypeRepresentation::Method:
1286-
case SILFunctionTypeRepresentation::ObjCMethod:
12871286
return ty->isPolymorphic();
12881287

1288+
case SILFunctionTypeRepresentation::ObjCMethod:
1289+
// May be polymorphic at the SIL level, but no type metadata is actually
1290+
// passed.
1291+
return false;
1292+
12891293
case SILFunctionTypeRepresentation::WitnessMethod:
12901294
// Always carries polymorphic parameters for the Self type.
12911295
return true;
@@ -1482,8 +1486,6 @@ namespace {
14821486

14831487
private:
14841488
void initGenerics() {
1485-
assert(hasPolymorphicParameters(FnType));
1486-
14871489
// The canonical mangling signature removes dependent types that are
14881490
// equal to concrete types, but isn't necessarily parallel with
14891491
// substitutions.

lib/IRGen/IRGenSIL.cpp

+8-10
Original file line numberDiff line numberDiff line change
@@ -1290,16 +1290,14 @@ static void emitEntryPointArgumentsCOrObjC(IRGenSILFunction &IGF,
12901290

12911291
assert(params.empty() && "didn't claim all parameters!");
12921292

1293-
// Bind polymorphic arguments. This can only be done after binding
1294-
// all the value parameters.
1295-
if (hasPolymorphicParameters(funcTy)) {
1296-
emitPolymorphicParameters(IGF, *IGF.CurSILFn, params,
1297-
nullptr,
1298-
[&](unsigned paramIndex) -> llvm::Value* {
1299-
SILValue parameter = entry->getBBArgs()[paramIndex];
1300-
return IGF.getLoweredSingletonExplosion(parameter);
1301-
});
1302-
}
1293+
// Bind polymorphic arguments. This can only be done after binding
1294+
// all the value parameters, and must be done even for non-polymorphic
1295+
// functions because of imported Objective-C generics.
1296+
emitPolymorphicParameters(IGF, *IGF.CurSILFn, params, nullptr,
1297+
[&](unsigned paramIndex) -> llvm::Value* {
1298+
SILValue parameter = entry->getBBArgs()[paramIndex];
1299+
return IGF.getLoweredSingletonExplosion(parameter);
1300+
});
13031301
}
13041302

13051303
/// Get metadata for the dynamic Self type if we have it.

test/Interpreter/imported_objc_generics.swift

+1-2
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,7 @@ ImportedObjCGenerics.test("ProtocolConstraints") {
102102
}
103103

104104
let cs = CopyingContainer<NSString>(object: "Happy 2012")
105-
// TODO: Fixed in next commit.
106-
// expectEqual("Happy 2012", copyContainerContents(cs))
105+
expectEqual("Happy 2012", copyContainerContents(cs))
107106
}
108107

109108
ImportedObjCGenerics.test("ClassConstraints") {

0 commit comments

Comments
 (0)