diff --git a/Sources/Foundation/NSString.swift b/Sources/Foundation/NSString.swift index 11872e1593..dbe94c8b17 100644 --- a/Sources/Foundation/NSString.swift +++ b/Sources/Foundation/NSString.swift @@ -1644,3 +1644,24 @@ extension NSString : _StructTypeBridgeable { return _StructType._unconditionallyBridgeFromObjectiveC(self) } } + +extension NSString : CVarArg { + @inlinable // c-abi + public var _cVarArgEncoding: [Int] { + return _encodeBitsAsWords(unsafeBitCast(self, to: AnyObject.self)) + } +} + +#if !_runtime(_ObjC) +extension String : CVarArg, _CVarArgObject { + @inlinable // c-abi + public var _cVarArgObject: CVarArg { + return NSString(string: self) + } + + @inlinable // c-abi + public var _cVarArgEncoding: [Int] { + fatalError("_cVarArgEncoding must be called on NSString instead") + } +} +#endif diff --git a/Tests/Foundation/Tests/TestNSString.swift b/Tests/Foundation/Tests/TestNSString.swift index 90ecb00d05..57e56c69a2 100644 --- a/Tests/Foundation/Tests/TestNSString.swift +++ b/Tests/Foundation/Tests/TestNSString.swift @@ -813,6 +813,15 @@ class TestNSString: LoopbackServerTest { } } + func test_initializeWithFormat4() { + let argument: [CVarArg] = ["One", "Two", "Three"] + withVaList(argument) { + pointer in + let string = NSString(format: "Testing %@ %@ %@", arguments: pointer) + XCTAssertEqual(string, "Testing One Two Three") + } + } + func test_appendingPathComponent() { do { let path: NSString = "/tmp" @@ -1677,6 +1686,7 @@ class TestNSString: LoopbackServerTest { ("test_initializeWithFormat", test_initializeWithFormat), ("test_initializeWithFormat2", test_initializeWithFormat2), ("test_initializeWithFormat3", test_initializeWithFormat3), + ("test_initializeWithFormat4", test_initializeWithFormat4), ("test_appendingPathComponent", test_appendingPathComponent), ("test_deletingLastPathComponent", test_deletingLastPathComponent), ("test_getCString_simple", test_getCString_simple),