Files
swift-mirror/test/Constraints/swift_to_c_pointer_conversions.swift.gyb
Pavel Yaskevich 55b8d9538d [CSSimplify] Rework how/when mismatches between optional types are fixed
- Don't attempt to insert fixes if there are restrictions present, they'd inform the failures.

  Inserting fixes too early doesn't help the solver because restriction matching logic would
  record the same fixes.

- Adjust impact of the fixes.

  Optional conversions shouldn't impact the score in any way because
  they are not the source of the issue.

- Look through one level of optional when failure is related to optional injection.

  The diagnostic is going to be about underlying type, so there is no reason to print
  optional on right-hand side.
2024-09-10 10:35:05 -07:00

333 lines
13 KiB
Swift

// RUN: %empty-directory(%t)
// RUN: %gyb %s -o %t/swift_to_c_pointer_conversions.swift
// RUN: %line-directive %t/swift_to_c_pointer_conversions.swift -- %target-swift-frontend(mock-sdk: %clang-importer-sdk-nosource -I %t) -import-objc-header %S/Inputs/c_pointer_conversions.h %t/swift_to_c_pointer_conversions.swift -typecheck -verify
// REQUIRES: objc_interop
func test_raw_ptr(ptr: UnsafeRawPointer) {
char_ptr_func(ptr) // expected-error {{}}
unsigned_char_ptr_func(ptr) // expected-error {{}}
const_char_ptr_func(ptr) // Ok
const_unsigned_char_ptr_func(ptr) // Ok
% for Size in ['16', '32', '64']:
int_${Size}_ptr_func(ptr) // expected-error {{}}
uint_${Size}_ptr_func(ptr) // expected-error {{}}
const_int_${Size}_ptr_func(ptr) // expected-error {{}}
const_uint_${Size}_ptr_func(ptr) // expected-error {{}}
% end
}
func test_mutable_raw_pointer(ptr: UnsafeMutableRawPointer) {
char_ptr_func(ptr) // Ok
unsigned_char_ptr_func(ptr) // Ok
const_char_ptr_func(ptr) // Ok
const_unsigned_char_ptr_func(ptr) // Ok
% for Size in ['16', '32', '64']:
int_${Size}_ptr_func(ptr) // expected-error {{}}
uint_${Size}_ptr_func(ptr) // expected-error {{}}
const_int_${Size}_ptr_func(ptr) // expected-error {{}}
const_uint_${Size}_ptr_func(ptr) // expected-error {{}}
% end
}
%for TestPtrSize in ['8', '16', '32', '64']:
// Immutable pointers can be converted only to their immutable (regardless of sign) counterparts.
func test_${TestPtrSize}_bit_ptrs(sptr: UnsafePointer<Int${TestPtrSize}>,
uptr: UnsafePointer<UInt${TestPtrSize}>,
osptr: UnsafePointer<Int${TestPtrSize}>?,
ouptr: UnsafePointer<UInt${TestPtrSize}>?) {
% for pointer in ['sptr', 'uptr']:
char_ptr_func(${pointer}) // expected-error {{}}
opt_char_ptr_func(${pointer}) // expected-error {{}}
const_char_ptr_func(${pointer}) // Ok
const_opt_char_ptr_func(${pointer}) // Ok
unsigned_char_ptr_func(${pointer}) // expected-error {{}}
unsigned_opt_char_ptr_func(${pointer}) // expected-error {{}}
const_unsigned_char_ptr_func(${pointer}) // Ok
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
% end
% for pointer in ['osptr', 'ouptr']:
opt_char_ptr_func(${pointer}) // expected-error {{}}
const_opt_char_ptr_func(${pointer}) // Ok
unsigned_opt_char_ptr_func(${pointer}) // expected-error {{}}
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
% end
% for pointer in ['sptr', 'uptr']:
% for Size in ['16', '32', '64']:
% if Size == TestPtrSize:
int_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
uint_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
opt_int_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
const_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
% else:
int_${Size}_ptr_func(${pointer}) // expected-error {{}}
uint_${Size}_ptr_func(${pointer}) // expected-error {{}}
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}}
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}}
const_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
% end
% end
% end
% for pointer in ['osptr', 'ouptr']:
% for Size in ['16', '32', '64']:
% if Size == TestPtrSize:
opt_int_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // expected-error {{}}
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
% else:
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}}
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}}
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
% end
% end
% end
}
% end
%for TestPtrSize in ['8', '16', '32', '64']:
// Mutable pointers can be converted to both immutable and mutable pointers when
// passed to C/ObjC imported functions.
func test_mutable_${TestPtrSize}_bit_ptrs(sptr: UnsafeMutablePointer<Int${TestPtrSize}>,
uptr: UnsafeMutablePointer<UInt${TestPtrSize}>,
osptr: UnsafeMutablePointer<Int${TestPtrSize}>?,
ouptr: UnsafeMutablePointer<UInt${TestPtrSize}>?) {
% for pointer in ['sptr', 'uptr']:
char_ptr_func(${pointer}) // Ok
opt_char_ptr_func(${pointer}) // Ok
const_char_ptr_func(${pointer}) // Ok
const_opt_char_ptr_func(${pointer}) // Ok
unsigned_char_ptr_func(${pointer}) // Ok
opt_unsigned_char_ptr_func(${pointer}) // Ok
const_unsigned_char_ptr_func(${pointer}) // Ok
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
% end
% for pointer in ['osptr', 'ouptr']:
opt_char_ptr_func(${pointer}) // Ok
const_opt_char_ptr_func(${pointer}) // Ok
opt_unsigned_char_ptr_func(${pointer}) // Ok
const_opt_unsigned_char_ptr_func(${pointer}) // Ok
% end
% for pointer in ['sptr', 'uptr']:
% for Size in ['16', '32', '64']:
% if Size == TestPtrSize:
int_${TestPtrSize}_ptr_func(${pointer}) // Ok
uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
% else:
int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
% end
% end
% end
% for pointer in ['osptr', 'ouptr']:
% for Size in ['16', '32', '64']:
% if Size == TestPtrSize:
opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_int_${TestPtrSize}_ptr_func(${pointer}) // Ok
const_opt_uint_${TestPtrSize}_ptr_func(${pointer}) // Ok
% else:
opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_int_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
const_opt_uint_${Size}_ptr_func(${pointer}) // expected-error {{}} expected-note {{}}
% end
% end
% end
}
% end
func test_raw_ptr_value_to_optional_promotion(
riptr: UnsafeRawPointer,
rmptr: UnsafeMutableRawPointer) {
opt_char_ptr_func(riptr) // expected-error {{}}
const_opt_char_ptr_func(riptr) // Ok
opt_char_ptr_func(rmptr) // Ok
const_opt_char_ptr_func(rmptr) // Ok
opt_unsigned_char_ptr_func(riptr) // expected-error {{}}
const_opt_unsigned_char_ptr_func(riptr) // Ok
opt_unsigned_char_ptr_func(rmptr) // Ok
const_opt_unsigned_char_ptr_func(rmptr) // Ok
% for Ptr in ['riptr', 'rmptr']:
% for Size in ['16', '32', '64']:
opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
const_opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
const_opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
% end
% end
}
func test_raw_ptr_optional_to_optional_conversion(
riptr: UnsafeRawPointer?,
rmptr: UnsafeMutableRawPointer?) {
opt_char_ptr_func(riptr) // expected-error {{}}
const_opt_char_ptr_func(riptr) // Ok
opt_char_ptr_func(rmptr) // Ok
const_opt_char_ptr_func(rmptr) // Ok
opt_unsigned_char_ptr_func(rmptr) // Ok
const_opt_unsigned_char_ptr_func(rmptr) // Ok
% for Ptr in ['riptr', 'rmptr']:
% for Size in ['16', '32', '64']:
opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
const_opt_int_${Size}_ptr_func(${Ptr}) // expected-error {{}}
const_opt_uint_${Size}_ptr_func(${Ptr}) // expected-error {{}}
% end
% end
}
// Check that implicit conversions don't make expressions ambiguous
func test_overloaded_ref_is_not_ambiguous() {
func overloaded_func() -> UnsafeRawPointer { fatalError() }
func overloaded_func() -> UnsafePointer<Int8> { fatalError() }
const_char_ptr_func(overloaded_func()) // Ok
const_opt_char_ptr_func(overloaded_func()) // Ok
}
func test_tailored_diagnostic(ptr: UnsafeRawPointer, tptr: UnsafePointer<Int8>) {
func swift_uint8_func(_: UnsafePointer<UInt8>) {}
func swift_int8_func(_: UnsafePointer<Int8>) {}
func opt_arg_func(_: UnsafePointer<Int8>?) {}
swift_uint8_func(ptr)
// expected-error@-1 {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafePointer<UInt8>' because local function 'swift_uint8_func' was not imported from C header}}
swift_uint8_func(tptr)
// expected-error@-1 {{cannot convert value of type 'UnsafePointer<Int8>' to expected argument type 'UnsafePointer<UInt8>' because local function 'swift_uint8_func' was not imported from C header}}
swift_int8_func(ptr)
// expected-error@-1 {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafePointer<Int8>' because local function 'swift_int8_func' was not imported from C header}}
swift_int8_func(tptr) // Ok
opt_arg_func(ptr)
// expected-error@-1 {{cannot convert value of type 'UnsafeRawPointer' to expected argument type 'UnsafePointer<Int8>?' because local function 'opt_arg_func' was not imported from C header}}
opt_arg_func(tptr) // Ok
let optrS8: UnsafePointer<Int8>? = nil
let optrU8: UnsafePointer<UInt8>? = nil
opt_arg_func(optrS8) // Ok
opt_arg_func(optrU8)
// expected-error@-1 {{cannot convert value of type 'UnsafePointer<UInt8>?' to expected argument type 'UnsafePointer<Int8>?' because local function 'opt_arg_func' was not imported from C header}}
}
func test_inout_to_pointer_conversion() {
% for Size in ['16', '32', '64']:
var x${Size}: Int${Size} = 0
void_ptr_func(&x${Size}) // Ok
const_void_ptr_func(&x${Size}) // Ok
opt_void_ptr_func(&x${Size}) // Ok
char_ptr_func(&x${Size}) // Ok
opt_char_ptr_func(&x${Size}) // Ok
const_char_ptr_func(&x${Size}) // Ok
const_opt_char_ptr_func(&x${Size}) // Ok
int_${Size}_ptr_func(&x${Size}) // Ok
uint_${Size}_ptr_func(&x${Size}) // Ok
opt_int_${Size}_ptr_func(&x${Size}) // Ok
opt_uint_${Size}_ptr_func(&x${Size}) // Ok
const_int_${Size}_ptr_func(&x${Size}) // OK
const_uint_${Size}_ptr_func(&x${Size}) // OK
const_opt_int_${Size}_ptr_func(&x${Size}) // OK
const_opt_uint_${Size}_ptr_func(&x${Size}) // OK
% end
}
func test_array_to_pointer_conversion() {
% for Size in ['16', '32', '64']:
var x${Size}: [Int${Size}] = []
void_ptr_func(&x${Size}) // Ok
const_void_ptr_func(x${Size}) // Ok
opt_void_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutableRawPointer'}}
char_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<CChar>' (aka 'UnsafeMutablePointer<Int8>')}}
opt_char_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<CChar>' (aka 'UnsafeMutablePointer<Int8>')}}
const_char_ptr_func(x${Size}) // Ok
const_opt_char_ptr_func(x${Size}) // Ok
int_${Size}_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<Int${Size}>'}}
uint_${Size}_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<UInt${Size}>'}}
opt_int_${Size}_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<Int${Size}>'}}
opt_uint_${Size}_ptr_func(x${Size})
// expected-error@-1 {{cannot convert value of type '[Int${Size}]' to expected argument type 'UnsafeMutablePointer<UInt${Size}>'}}
const_int_${Size}_ptr_func(x${Size}) // OK
const_uint_${Size}_ptr_func(x${Size}) // OK
const_opt_int_${Size}_ptr_func(x${Size}) // OK
const_opt_uint_${Size}_ptr_func(x${Size}) // OK
% end
}