Skip to content

Commit 85862b0

Browse files
committed
NCGenerics: fix partial backdeployment support
When the type substitution is concrete, we can obtain metadata on older runtimes for the type with a noncopyable generic parameter. We just have to avoid the demangling strategy. resolves rdar://126239335
1 parent 84a0779 commit 85862b0

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,20 @@ getRuntimeVersionThatSupportsDemanglingType(CanType type) {
226226
// involving them.
227227
}
228228

229+
// Any nominal type that has an inverse requirement in its generic signature
230+
// uses NoncopyableGenerics. Since inverses are mangled into symbols,
231+
// a Swift 6.0+ runtime is needed to demangle them.
232+
if (auto nominalTy = dyn_cast<NominalOrBoundGenericNominalType>(t)) {
233+
auto *nom = nominalTy->getDecl();
234+
if (auto sig = nom->getGenericSignature()) {
235+
SmallVector<InverseRequirement, 2> inverses;
236+
SmallVector<Requirement, 2> reqs;
237+
sig->getRequirementsWithInverses(reqs, inverses);
238+
if (!inverses.empty())
239+
return addRequirement(Swift_6_0);
240+
}
241+
}
242+
229243
return false;
230244
});
231245

@@ -358,6 +372,7 @@ getTypeRefByFunction(IRGenModule &IGM,
358372
Address(bindingsBufPtr, IGM.Int8Ty, IGM.getPointerAlignment()),
359373
MetadataState::Complete, subs);
360374

375+
substT = substT.getReferenceStorageReferent(); // FIXME: shot in the dark here
361376
auto ret = IGF.emitTypeMetadataRef(substT);
362377
IGF.Builder.CreateRet(ret);
363378
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %swift-frontend %s -swift-version 6 -module-name main -emit-ir -o %t/new.ir
3+
// RUN: %FileCheck %s --check-prefix=NEW < %t/new.ir
4+
// RUN: %target-swift-frontend %s -target %target-cpu-apple-macosx10.15 -module-name main -emit-ir -o %t/old.ir
5+
// RUN: %FileCheck %s --check-prefix=OLD < %t/old.ir
6+
7+
// Check that we add extra type metadata accessors for types with generic
8+
// parameters that have an inverse. These are used instead of using demangling
9+
// cache variables since old runtimes cannot synthesize type metadata based on
10+
// the new mangling.
11+
12+
// RUN: %target-build-swift -target %target-cpu-apple-macosx10.15 %s -o %t/test_mangling
13+
// RUN: %target-run %t/test_mangling | %FileCheck %s
14+
15+
// REQUIRES: OS=macosx
16+
// REQUIRES: executable_test
17+
18+
19+
// This type's generic parameter is noncopyable, so older runtimes can't
20+
// demangle the type's name to build the metadata.
21+
struct Foo<T: ~Copyable>: ~Copyable {
22+
mutating func bar() { print("Foo.bar") }
23+
}
24+
25+
func test() {
26+
var foo = Foo<Int>()
27+
foo.bar()
28+
}
29+
test()
30+
// CHECK: Foo.bar
31+
32+
// NEW: define hidden swiftcc void @"$s4main4testyyF"()
33+
// NEW-NOT: %swift.metadata_response
34+
// NEW: call ptr @__swift_instantiateConcreteTypeFromMangledName(ptr @"$s4main3FooVySiGMD")
35+
// NEW-NOT: %swift.metadata_response
36+
// NEW: }
37+
38+
// OLD: define hidden swiftcc void @"$s4main4testyyF"()
39+
// OLD-NOT: __swift_instantiateConcreteTypeFromMangledName
40+
// OLD: call swiftcc %swift.metadata_response @"$s4main3FooVySiGMa"(i64 0)
41+
// OLD-NOT: __swift_instantiateConcreteTypeFromMangledName
42+
// OLD: }
43+
44+
45+
// This type does not need a Swift 6.0 runtime, despite being noncopyable,
46+
// because it doesn't have a noncopyable generic parameter.
47+
struct JustNoncopyable<T>: ~Copyable {
48+
mutating func bar() { print("JustNoncopyable.bar") }
49+
}
50+
51+
func testNonGeneric() {
52+
var ng = JustNoncopyable<Int>()
53+
ng.bar()
54+
}
55+
testNonGeneric()
56+
57+
// CHECK: JustNoncopyable.bar
58+
59+
// NEW: define hidden swiftcc void @"$s4main14testNonGenericyyF"()
60+
// NEW-NOT: %swift.metadata_response
61+
// NEW: call ptr @__swift_instantiateConcreteTypeFromMangledName(ptr @"$s4main15JustNoncopyableVySiGMD")
62+
// NEW-NOT: %swift.metadata_response
63+
// NEW: }
64+
65+
// OLD: define hidden swiftcc void @"$s4main14testNonGenericyyF"()
66+
// OLD-NOT: %swift.metadata_response
67+
// OLD: call ptr @__swift_instantiateConcreteTypeFromMangledName(ptr @"$s4main15JustNoncopyableVySiGMD")
68+
// OLD-NOT: %swift.metadata_response
69+
// OLD: }

0 commit comments

Comments
 (0)