1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
|
// RUN: %target-typecheck-verify-swift -swift-version 5
// REQUIRES: VENDOR=apple
// Tests the constantness Sema diagnostics for the OSLogTestHelper module,
// which acts as a stub for the os overlay.
import OSLogTestHelper
func testDynamicLogMessage(message: OSLogMessage) {
_osLogTestHelper(message)
// expected-error@-1 {{argument must be a string interpolation}}
}
func testNonconstantFormatOption(
formatOpt: OSLogIntegerFormatting,
explicitPositiveSign: Bool) {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
let uppercase = true
_osLogTestHelper("\(UInt.max, format: .hex(uppercase: uppercase))")
// expected-error@-1 {{argument must be a bool literal}}
_osLogTestHelper("\(UInt.max, format: .hex)") // No error is expected here.
}
func testNonconstantPrivacyOption(privacyOpt: OSLogPrivacy) {
_osLogTestHelper("Integer: \(Int.max, privacy: privacyOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogPrivacy'}}
}
func testNonconstantAlignmentOption(alignOpt: OSLogStringAlignment) {
_osLogTestHelper("Integer: \(Int.max, align: alignOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogStringAlignment'}}
}
func testMultipleOptions(
formatOpt: OSLogIntegerFormatting,
privacyOpt: OSLogPrivacy
) {
_osLogTestHelper(
"""
\(2, format: formatOpt, align: .right(columns: 10), privacy: privacyOpt)
""")
// expected-error@-2 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
// expected-error@-3 {{argument must be a static method or property of 'OSLogPrivacy'}}
}
func testNoninlinedOSLogMessage() {
let logMessage: OSLogMessage = "Minimum integer value: \(Int.min)"
_osLogTestHelper(logMessage)
// expected-error@-1 {{argument must be a string interpolation}}
}
let globalLogMessage: OSLogMessage = "A global message"
func testGlobalLogMessage() {
_osLogTestHelper(globalLogMessage)
// expected-error@-1 {{argument must be a string interpolation}}
}
// No errors are expected here.
func testValidLogCalls(x: Int) {
_osLogTestHelper("\(x, format: .hex, privacy: .private)")
_osLogTestHelper("\(x, format: OSLogIntegerFormatting.hex, privacy: .public)")
_osLogTestHelper("\(x, privacy: OSLogPrivacy.public)")
_osLogTestHelper("\((x + 1) * 2, privacy: .public)")
}
// Check whether os-log-specific diagnostics do not crash when there
// are type errors.
func testTypeIncorrectLogCalls() {
let message = "test message"
class TestClass {
}
let x = TestClass()
_osLogTestHelper(message)
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'OSLogMessage'}}
_osLogTestHelper("prefix" + "\(x)")
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type 'OSLogMessage'}}
_osLogTestHelper("prefix", "\(x)")
// expected-error@-1 {{cannot convert value of type 'String' to expected argument type '(String, UnsafeBufferPointer<UInt8>) -> Void'}}
// expected-error@-2 {{missing argument label 'assertion:' in call}}
_osLogTestHelper("\(x, format: .hex)")
//expected-error@-1 {{no exact matches in call to instance method 'appendInterpolation'}}
_osLogTestHelper("\(10, format: .myFormat, privacy: .private)")
//expected-error@-1 {{type 'OSLogIntegerFormatting' has no member 'myFormat'}}
}
// Test diagnostics in extensions to OSLogInterpolation. This is not officially
// supported yet.
struct MyStruct {
var i: Int
}
extension OSLogInterpolation {
mutating func appendInterpolation(a: MyStruct) {
self.appendInterpolation(a.i)
}
mutating func appendInterpolation(a: MyStruct, format: OSLogIntegerFormatting) {
self.appendInterpolation(a.i, format: format)
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
@_semantics("oslog.requires_constant_arguments")
mutating func appendInterpolation(a: MyStruct, constFormat: OSLogIntegerFormatting) {
self.appendInterpolation(a.i, format: constFormat)
}
}
func testOSLogInterpolationExtension(a: MyStruct) {
// The following is not a Sema error but would result in SIL diagnostics as
// the appendInterpolation overload is not marked as constant_evaluable.
_osLogTestHelper("Error at line: \(a: a)")
}
func testExplicitOSLogMessageConstruction() {
_osLogTestHelper(OSLogMessage(stringLiteral: "world"))
// expected-error@-1 {{argument must be a string interpolation}}
_osLogTestHelper(
OSLogMessage( // expected-error {{argument must be a string interpolation}}
stringInterpolation:
OSLogInterpolation(
literalCapacity: 0,
interpolationCount: 0)))
}
// Test that @_semantics("oslog.log_with_level") permits values of type OSLog and
// OSLogType to not be constants.
class OSLog { }
class OSLogType { }
@_semantics("oslog.log_with_level")
func osLogWithLevel(_ level: OSLogType, log: OSLog, _ message: OSLogMessage) {
}
func testNonConstantLogObjectLevel(
level: OSLogType,
log: OSLog,
message: OSLogMessage
) {
osLogWithLevel(level, log: log, "message with no payload")
var levelOpt: OSLogType? = nil
levelOpt = level
let logClosure = { log }
osLogWithLevel(levelOpt!, log: logClosure(), "A string \("hello")")
osLogWithLevel(level, log: log, message)
// expected-error@-1 {{argument must be a string interpolation}}
}
// Test that log messages can be wrapped in constant_evaluable functions.
// A function similar to the one used by SwiftUI preview to wrap string
// literals.
@_semantics("constant_evaluable")
public func __designTimeStringStub(
_ key: String,
fallback: OSLogMessage
) -> OSLogMessage {
fallback
}
func testSwiftUIPreviewWrapping() {
// This should not produce any diagnostics.
_osLogTestHelper(__designTimeStringStub("key", fallback: "A literal message"))
}
public func nonConstantFunction(
_ key: String,
fallback: OSLogMessage
) -> OSLogMessage {
fallback
}
func testLogMessageWrappingDiagnostics() {
_osLogTestHelper(nonConstantFunction("key", fallback: "A literal message"))
// expected-error@-1{{argument must be a string interpolation}}
}
// Test closure expressions
func funcAcceptingClosure<T>(_ x: () -> T) -> T {
return x()
}
func normalFunction() {}
func testCallsWithinClosures(formatOpt: OSLogIntegerFormatting) {
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
_osLogTestHelper("Maximum integer value: \(Int.max, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
funcAcceptingClosure {
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
}
funcAcceptingClosure {
normalFunction()
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: formatOpt)")
// expected-error@-1 {{argument must be a static method or property of 'OSLogIntegerFormatting'}}
}
}
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: .hex)")
}
funcAcceptingClosure {
_osLogTestHelper("Minimum integer value: \(Int.min, format: .hex)")
_osLogTestHelper("Maximum integer value: \(Int.max, privacy: .public)")
}
}
|