Skip to content

Commit cb76d0a

Browse files
Kyle Macomberairspeedswift
Kyle Macomber
andauthored
[5.3] Add fast string interpolation for metatypes (#32958)
* Add fast string interpolation for metatypes (#32113) * Whitespace fixes Co-authored-by: Ben Cohen <[email protected]>
1 parent a7542a5 commit cb76d0a

File tree

3 files changed

+112
-2
lines changed

3 files changed

+112
-2
lines changed

stdlib/public/core/StringInterpolation.swift

+6-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,12 @@ public struct DefaultStringInterpolation: StringInterpolationProtocol {
178178
public mutating func appendInterpolation<T>(_ value: T) {
179179
_print_unlocked(value, &self)
180180
}
181-
181+
182+
@_alwaysEmitIntoClient
183+
public mutating func appendInterpolation(_ value: Any.Type) {
184+
_typeName(value, qualified: false).write(to: &self)
185+
}
186+
182187
/// Creates a string from this instance, consuming the instance in the
183188
/// process.
184189
@inlinable

test/IDE/complete_at_top_level.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ var stringInterp = "\(#^STRING_INTERP_3^#)"
471471
_ = "" + "\(#^STRING_INTERP_4^#)" + ""
472472
// STRING_INTERP: Begin completions
473473
// STRING_INTERP-DAG: Decl[InstanceMethod]/CurrNominal/IsSystem: ['(']{#(value): T#}[')'][#Void#];
474-
// STRING_INTERP-DAG: Decl[Struct]/CurrModule: FooStruct[#FooStruct#];
474+
// STRING_INTERP-DAG: Decl[Struct]/CurrModule/TypeRelation[Convertible]: FooStruct[#FooStruct#]; name=FooStruct
475475
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule/TypeRelation[Invalid]: fooFunc1()[#Void#];
476476
// STRING_INTERP-DAG: Decl[FreeFunction]/CurrModule: optStr()[#String?#];
477477
// STRING_INTERP-DAG: Decl[GlobalVar]/Local: fooObject[#FooStruct#];
+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// RUN: %target-build-swift -O %s -module-name=test -Xfrontend -sil-verify-all -emit-sil | %FileCheck %s
2+
// RUN: %target-build-swift -Onone %s -module-name=test -Xfrontend -sil-verify-all -emit-sil | %FileCheck %s
3+
// RUN: %target-run-simple-swift
4+
// REQUIRES: executable_test
5+
6+
import StdlibUnittest
7+
8+
let TypeNameTests = TestSuite("TypeName")
9+
10+
class C {}
11+
struct S {}
12+
enum E {}
13+
14+
protocol P {}
15+
protocol P2 {}
16+
protocol P3 {}
17+
protocol AssociatedTypes {
18+
associatedtype A
19+
associatedtype B
20+
associatedtype C
21+
}
22+
23+
class Model : AssociatedTypes {
24+
typealias A = C
25+
typealias B = S
26+
typealias C = E
27+
}
28+
29+
struct Model2 : AssociatedTypes {
30+
typealias A = C
31+
typealias B = S
32+
typealias C = E
33+
}
34+
35+
class GC<T : AssociatedTypes> {}
36+
struct GS<T : AssociatedTypes> {}
37+
enum GE<T : AssociatedTypes> {}
38+
class GC2<T : AssociatedTypes, U : AssociatedTypes> {}
39+
40+
class SomeOuterClass {
41+
struct SomeInnerStruct {}
42+
struct SomeInnerGenericStruct<T> {}
43+
}
44+
45+
class SomeOuterGenericClass<T> {
46+
struct SomeInnerStruct {}
47+
struct SomeInnerGenericStruct<U> {}
48+
}
49+
50+
extension SomeOuterGenericClass {
51+
struct OtherInnerStruct {}
52+
struct OtherInnerGenericStruct<U> {}
53+
}
54+
55+
@inline(never)
56+
func printTypename(_ s: String) {
57+
print(s)
58+
}
59+
60+
// CHECK-LABEL: sil {{.*}} @$s4test0A21TypenameInterpolationyyF :
61+
// CHECK-NOT: $ss26DefaultStringInterpolationV06appendC0yyxlF
62+
// CHECK-NOT: _print_unlocked
63+
// CHECK: } // end sil function '$s4test0A21TypenameInterpolationyyF'
64+
@inline(never)
65+
func testTypenameInterpolation() {
66+
expectEqual("Int", "\(Int.self)")
67+
expectEqual("C", "\(C.self)")
68+
expectEqual("S", "\(S.self)")
69+
expectEqual("E", "\(E.self)")
70+
expectEqual("GC<Model>",
71+
"\(GC<Model>.self)")
72+
expectEqual("GS<Model>",
73+
"\(GS<Model>.self)")
74+
expectEqual("GE<Model>",
75+
"\(GE<Model>.self)")
76+
expectEqual("GC2<Model, Model2>",
77+
"\(GC2<Model, Model2>.self)")
78+
79+
expectEqual("P", "\(P.self)")
80+
typealias PP2 = P & P2
81+
expectEqual("P & P2",
82+
"\(PP2.self)")
83+
expectEqual("Any", "\(Any.self)")
84+
expectEqual("P & P2", "\((P & P2).self)")
85+
86+
87+
expectEqual("SomeInnerStruct",
88+
"\(SomeOuterClass.SomeInnerStruct.self)")
89+
expectEqual("SomeInnerGenericStruct<Int>",
90+
"\(SomeOuterClass.SomeInnerGenericStruct<Int>.self)")
91+
expectEqual("SomeInnerStruct",
92+
"\(SomeOuterGenericClass<Int>.SomeInnerStruct.self)")
93+
expectEqual("SomeInnerGenericStruct<Int>",
94+
"\(SomeOuterGenericClass<String>.SomeInnerGenericStruct<Int>.self)")
95+
expectEqual("OtherInnerStruct",
96+
"\(SomeOuterGenericClass<Int>.OtherInnerStruct.self)")
97+
expectEqual("OtherInnerGenericStruct<String>",
98+
"\(SomeOuterGenericClass<Int>.OtherInnerGenericStruct<String>.self)")
99+
}
100+
101+
TypeNameTests.test("Interpolation") {
102+
testTypenameInterpolation()
103+
}
104+
105+
runAllTests()

0 commit comments

Comments
 (0)