// RUN: %empty-directory(%t) // RUN: %gyb -DOPT_KIND=None %s -o %t/pointer_conversion.swift // RUN: %line-directive %t/pointer_conversion.swift -- %target-swift-frontend -typecheck -verify %t/pointer_conversion.swift // RUN: %gyb -DOPT_KIND=Optional %s -o %t/pointer_conversion_opt.swift // RUN: %line-directive %t/pointer_conversion_opt.swift -- %target-swift-frontend -typecheck -verify %t/pointer_conversion_opt.swift // RUN: %gyb -DOPT_KIND=ImplicitlyUnwrappedOptional %s -o %t/pointer_conversion_iuo.swift // RUN: %line-directive %t/pointer_conversion_iuo.swift -- %target-swift-frontend -typecheck -verify %t/pointer_conversion_iuo.swift %{ if OPT_KIND == 'Optional': suffix='?' elif OPT_KIND == 'ImplicitlyUnwrappedOptional': suffix='!' else: suffix='' }% class C {} class D {} func takesMutablePointer(_ x: UnsafeMutablePointer${suffix}) {} func takesMutableVoidPointer(_ x: UnsafeMutableRawPointer${suffix}) {} func takesMutableRawPointer(_ x: UnsafeMutableRawPointer${suffix}) {} func takesMutableInt8Pointer(_ x: UnsafeMutablePointer${suffix}) {} func takesMutableArrayPointer(_ x: UnsafeMutablePointer<[Int]>${suffix}) {} @discardableResult func takesConstPointer(_ x: UnsafePointer${suffix}) -> Character { return "x" } func takesConstInt8Pointer(_ x: UnsafePointer${suffix}) {} func takesConstUInt8Pointer(_ x: UnsafePointer${suffix}) {} func takesConstVoidPointer(_ x: UnsafeRawPointer${suffix}) {} func takesConstRawPointer(_ x: UnsafeRawPointer${suffix}) {} func mutablePointerArguments(_ p: UnsafeMutablePointer, cp: UnsafePointer) { takesMutablePointer(nil) % if not suffix: // expected-error@-2 {{'nil' is not compatible with expected argument type}} % end takesMutablePointer(p) takesMutablePointer(cp) // expected-error{{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafeMutablePointer'}} var i: Int = 0 var f: Float = 0 takesMutablePointer(&i) takesMutablePointer(&f) // expected-error{{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}} takesMutablePointer(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'UnsafeMutablePointer'}} takesMutablePointer(f) // expected-error{{cannot convert value of type 'Float' to expected argument type 'UnsafeMutablePointer'}} var ii: [Int] = [0, 1, 2] var ff: [Float] = [0, 1, 2] takesMutablePointer(&ii) takesMutablePointer(&ff) // expected-error{{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}} takesMutablePointer(ii) // expected-error{{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutablePointer'}} takesMutablePointer(ff) // expected-error{{cannot convert value of type '[Float]' to expected argument type 'UnsafeMutablePointer'}} takesMutableArrayPointer(&i) // expected-error{{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer<[Int]>'}} //expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int' and '[Int]') are expected to be equal}} takesMutableArrayPointer(&ii) // We don't allow these conversions outside of function arguments. var x: UnsafeMutablePointer = &i // expected-error {{'&' may only be used to pass an argument to inout parameter}} x = &ii // expected-error {{'&' may only be used to pass an argument to inout parameter}} _ = x } func mutableVoidPointerArguments(_ p: UnsafeMutablePointer, cp: UnsafePointer, fp: UnsafeMutablePointer) { takesMutableVoidPointer(nil) % if not suffix: // expected-error@-2 {{'nil' is not compatible with expected argument type}} % end takesMutableVoidPointer(p) takesMutableVoidPointer(fp) takesMutableVoidPointer(cp) // expected-error{{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafeMutableRawPointer'}} var i: Int = 0 var f: Float = 0 takesMutableVoidPointer(&i) takesMutableVoidPointer(&f) takesMutableVoidPointer(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableVoidPointer(f) // expected-error{{cannot convert value of type 'Float' to expected argument type 'UnsafeMutableRawPointer'}} var ii: [Int] = [0, 1, 2] var dd: [CInt] = [1, 2, 3] var ff: [Int] = [0, 1, 2] takesMutableVoidPointer(&ii) takesMutableVoidPointer(&dd) takesMutableVoidPointer(&ff) takesMutableVoidPointer(ii) // expected-error{{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableVoidPointer(ff) // expected-error{{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutableRawPointer'}} // We don't allow these conversions outside of function arguments. var x: UnsafeMutableRawPointer = &i // expected-error {{'&' may only be used to pass an argument to inout parameter}} x = p // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafeMutableRawPointer'}} x = &ii // expected-error {{'&' may only be used to pass an argument to inout parameter}} _ = x } func mutableRawPointerArguments(_ p: UnsafeMutablePointer, cp: UnsafePointer, fp: UnsafeMutablePointer, rp: UnsafeRawPointer) { takesMutableRawPointer(nil) % if not suffix: // expected-error@-2 {{'nil' is not compatible with expected argument type}} % end takesMutableRawPointer(p) takesMutableRawPointer(fp) takesMutableRawPointer(cp) // expected-error{{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableRawPointer(rp) // expected-error{{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafeMutableRawPointer'}} var i: Int = 0 var f: Float = 0 takesMutableRawPointer(&i) takesMutableRawPointer(&f) takesMutableRawPointer(i) // expected-error{{cannot convert value of type 'Int' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableRawPointer(f) // expected-error{{cannot convert value of type 'Float' to expected argument type 'UnsafeMutableRawPointer'}} var ii: [Int] = [0, 1, 2] var dd: [CInt] = [1, 2, 3] var ff: [Int] = [0, 1, 2] takesMutableRawPointer(&ii) takesMutableRawPointer(&dd) takesMutableRawPointer(&ff) takesMutableRawPointer(ii) // expected-error{{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableRawPointer(ff) // expected-error{{cannot convert value of type '[Int]' to expected argument type 'UnsafeMutableRawPointer'}} // We don't allow these conversions outside of function arguments. var x: UnsafeMutableRawPointer = &i // expected-error {{'&' may only be used to pass an argument to inout parameter}} x = p // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafeMutableRawPointer'}} x = &ii //expected-error {{'&' may only be used to pass an argument to inout parameter}} _ = x } func constPointerArguments(_ p: UnsafeMutablePointer, cp: UnsafePointer) { takesConstPointer(nil) % if not suffix: // expected-error@-2 {{'nil' is not compatible with expected argument type}} % end takesConstPointer(p) takesConstPointer(cp) var i: Int = 0 var f: Float = 0 takesConstPointer(&i) takesConstPointer(&f) // expected-error{{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}} var ii: [Int] = [0, 1, 2] var ff: [Float] = [0, 1, 2] takesConstPointer(&ii) takesConstPointer(&ff) // expected-error{{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}} takesConstPointer(ii) takesConstPointer(ff) // expected-error{{cannot convert value of type 'UnsafePointer' to expected argument type 'UnsafePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Float' and 'Int') are expected to be equal}} takesConstPointer([0, 1, 2]) // QoI: CSDiags doesn't handle array -> pointer impl conversions well takesConstPointer([0.0, 1.0, 2.0]) // expected-error@-1 3 {{cannot convert value of type 'Double' to expected element type 'Int'}} // We don't allow these conversions outside of function arguments. var x: UnsafePointer = &i // expected-error {{'&' may only be used to pass an argument to inout parameter}} x = ii // expected-error{{cannot assign value of type '[Int]' to type 'UnsafePointer'}} x = p // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafePointer'}} } func constVoidPointerArguments(_ p: UnsafeMutablePointer, fp: UnsafeMutablePointer, cp: UnsafePointer, cfp: UnsafePointer) { takesConstVoidPointer(nil) % if not suffix: // expected-error@-2 {{'nil' is not compatible with expected argument type}} % end takesConstVoidPointer(p) takesConstVoidPointer(fp) takesConstVoidPointer(cp) takesConstVoidPointer(cfp) var i: Int = 0 var f: Float = 0 takesConstVoidPointer(&i) takesConstVoidPointer(&f) var ii: [Int] = [0, 1, 2] var ff: [Float] = [0, 1, 2] takesConstVoidPointer(&ii) takesConstVoidPointer(&ff) takesConstVoidPointer(ii) takesConstVoidPointer(ff) takesConstVoidPointer([0, 1, 2]) takesConstVoidPointer([0.0, 1.0, 2.0]) // We don't allow these conversions outside of function arguments. var x: UnsafeRawPointer = &i // expected-error {{'&' may only be used to pass an argument to inout parameter}} x = ii // expected-error{{cannot assign value of type '[Int]' to type 'UnsafeRawPointer'}} x = p // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafeRawPointer'}} x = fp // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafeRawPointer'}} x = cp // expected-error{{cannot assign value of type 'UnsafePointer' to type 'UnsafeRawPointer'}} x = cfp // expected-error{{cannot assign value of type 'UnsafePointer' to type 'UnsafeRawPointer'}} _ = x } func constRawPointerArguments(_ p: UnsafeMutablePointer, fp: UnsafeMutablePointer, cp: UnsafePointer, cfp: UnsafePointer, mrp: UnsafeMutableRawPointer) { takesConstRawPointer(nil) % if not suffix: // expected-error@-2 {{'nil' is not compatible with expected argument type}} % end takesConstRawPointer(p) takesConstRawPointer(fp) takesConstRawPointer(cp) takesConstRawPointer(cfp) takesConstRawPointer(mrp) var i: Int = 0 var f: Float = 0 takesConstRawPointer(&i) takesConstRawPointer(&f) var ii: [Int] = [0, 1, 2] var ff: [Float] = [0, 1, 2] takesConstRawPointer(&ii) takesConstRawPointer(&ff) takesConstRawPointer(ii) takesConstRawPointer(ff) takesConstRawPointer([0, 1, 2]) takesConstRawPointer([0.0, 1.0, 2.0]) // We don't allow these conversions outside of function arguments. var x: UnsafeRawPointer = &i // expected-error {{'&' may only be used to pass an argument to inout parameter}} x = ii // expected-error{{cannot assign value of type '[Int]' to type 'UnsafeRawPointer'}} x = p // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafeRawPointer'}} x = fp // expected-error{{cannot assign value of type 'UnsafeMutablePointer' to type 'UnsafeRawPointer'}} x = cp // expected-error{{cannot assign value of type 'UnsafePointer' to type 'UnsafeRawPointer'}} x = cfp // expected-error{{cannot assign value of type 'UnsafePointer' to type 'UnsafeRawPointer'}} _ = x } func stringArguments(_ s: String) { var s = s takesConstVoidPointer(s) takesConstRawPointer(s) takesConstInt8Pointer(s) takesConstUInt8Pointer(s) takesConstPointer(s) // expected-error{{cannot convert value of type 'String' to expected argument type 'UnsafePointer'}} takesMutableVoidPointer(s) // expected-error{{cannot convert value of type 'String' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableRawPointer(s) // expected-error{{cannot convert value of type 'String' to expected argument type 'UnsafeMutableRawPointer'}} takesMutableInt8Pointer(s) // expected-error{{cannot convert value of type 'String' to expected argument type 'UnsafeMutablePointer'}} takesMutableInt8Pointer(&s) // expected-error{{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('String' and 'Int8') are expected to be equal}} takesMutablePointer(s) // expected-error{{cannot convert value of type 'String' to expected argument type 'UnsafeMutablePointer'}} takesMutablePointer(&s) // expected-error{{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('String' and 'Int') are expected to be equal}} } func optionality(_ op: UnsafeMutablePointer?) { takesMutableVoidPointer(op) % if not suffix: // expected-error@-2 {{value of optional type 'UnsafeMutablePointer?' must be unwrapped}} // expected-note@-3{{coalesce}} // expected-note@-4{{force-unwrap}} % end takesConstVoidPointer(op) % if not suffix: // expected-error@-2 {{value of optional type 'UnsafeMutablePointer?' must be unwrapped}} // expected-note@-3{{coalesce}} // expected-note@-4{{force-unwrap}} % end } func pointerArithmetic(_ x: UnsafeMutablePointer, y: UnsafeMutablePointer, i: Int) { _ = x + i _ = x - y } func genericPointerArithmetic(_ x: UnsafeMutablePointer, i: Int, t: T) -> UnsafeMutablePointer { let p = x + i p.initialize(to: t) } func passPointerToClosure(_ f: (UnsafeMutablePointer) -> Int) -> Int { } func pointerInClosure(_ f: (UnsafePointer) -> Int) -> Int { return passPointerToClosure { f($0) } } struct NotEquatable {} func arrayComparison(_ x: [NotEquatable], y: [NotEquatable], p: UnsafeMutablePointer) { var x = x // Don't allow implicit array-to-pointer conversions in operators. // There is a note attached to declaration - requirement from conditional conformance of '[NotEquatable]' to 'Equatable' let a: Bool = x == y // expected-error{{operator function '==' requires that 'NotEquatable' conform to 'Equatable'}} let _: Bool = p == &x // Allowed! } func addressConversion(p: UnsafeMutablePointer, x: Int) { var x = x let _: Bool = p == &x } // QoI: poor error: '&' used with non-inout argument of type 'UnsafeMutablePointer' func f19478919() { var viewport: Int = 1 // intentionally incorrect type, not Int32 func GLKProject(_ a : UnsafeMutablePointer) {} GLKProject(&viewport) // expected-error {{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int' and 'Int32') are expected to be equal}} func GLKProjectUP(_ a : UnsafePointer) {} func UP_Void(_ a : UnsafeRawPointer) {} func UMP_Void(_ a : UnsafeMutableRawPointer) {} UP_Void(&viewport) UMP_Void(&viewport) let cst = 42 // expected-note 2 {{change 'let' to 'var' to make it mutable}} UP_Void(&cst) // expected-error {{cannot pass immutable value as inout argument: 'cst' is a 'let' constant}} UMP_Void(&cst) // expected-error {{cannot pass immutable value as inout argument: 'cst' is a 'let' constant}} } // QoI: Poor diagnostic with let vs. var passed to C function func f23202128() { func UP(_ p: UnsafePointer) {} func UMP(_ p: UnsafeMutablePointer) {} let pipe: [Int32] = [0, 0] // expected-note {{change 'let' to 'var' to make it mutable}}}} UMP(&pipe) // expected-error {{cannot pass immutable value as inout argument: 'pipe' is a 'let' constant}} var pipe2: [Int] = [0, 0] UMP(&pipe2) // expected-error {{cannot convert value of type 'UnsafeMutablePointer' to expected argument type 'UnsafeMutablePointer'}} // expected-note@-1 {{arguments to generic parameter 'Pointee' ('Int' and 'Int32') are expected to be equal}} UP(pipe) // ok UP(&pipe) // expected-error {{'&' is not allowed passing array value as 'UnsafePointer' argument}} {{6-7=}} } func takesRawBuffer(_ b: UnsafeRawBufferPointer) {} // UnsafeRawBufferPointer range subscript is inconsistent with Collection. func f29586888(b: UnsafeRawBufferPointer) { takesRawBuffer(b[1..<2]) // expected-error {{'subscript(_:)' is unavailable: use 'UnsafeRawBufferPointer(rebasing:)' to convert a slice into a zero-based raw buffer.}} let slice = b[1..<2] takesRawBuffer(slice) // expected-error {{cannot convert value of type 'UnsafeRawBufferPointer.SubSequence' (aka 'Slice') to expected argument type 'UnsafeRawBufferPointer'}} }