Skip to content

Commit 116cb4c

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 51318b7 commit 116cb4c

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

lib/IRGen/GenReflection.cpp

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

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

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)