Error: type of expression is ambiguous without more context


I am trying address TODO in internal function _applyMapping of Unicode.Scalar.Properties

Here is my implementation using _FixedArray16:

internal func _applyMapping(_ u_strTo: _U_StrToX) -> String {
  let count = 64
  var array = _FixedArray16<UInt64>(allZeros: ()) // 16 * UInt64 take 128 bytes, same as 64 * UInt16
  let len: Int = array.withUnsafeMutableBufferPointer { bufPtr in
    return _scalar.withUTF16CodeUnits { utf16 in
      var err = __swift_stdlib_U_ZERO_ERROR
      let correctSize = u_strTo(
        UnsafeMutableRawPointer(bufPtr.baseAddress!).bindMemory(to: UInt16.self, capacity: count),
      guard err.isSuccess else {
        fatalError("Unexpected error case-converting Unicode scalar.")
      // TODO: _internalInvariant(count == correctSize, "inconsistent ICU behavior")
      return Int(correctSize)
  // TODO: replace `len` with `count`
  let result: String = array.withUnsafeBufferPointer{
// error: type of expression is ambiguous without more context
//    let result: String = array.withUnsafeBufferPointer{
//                             ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
    return String._uncheckedFromUTF16(UnsafeRawPointer($0).bindMemory(to: UInt16.self, capacity: len))
  return result

I am having compile error "type of expression is ambiguous without more context" as shown in snippet above.

Whatever I do I can't fix this compile error.

Any help is appreciated.

Valeriy Van

Let's try to go backwards.

_uncheckedFromUTF16 expects an UnsafeBufferPointer<UInt16>. However, the return type on UnsafeRawPointer.bindMemory(to:capacity:) is UnsafePointer. That seems to be tripping up the compiler. The correct thing (from a types perspective, I'm hardly an expert on memory binding) to do would be to create an UnsafeRawBufferPointer and then call bindMemory on it, which would give you an UnsafeBufferPointer.

Here's a verbose version:

let result = array.withUnsafeBufferPointer { (bp : UnsafeBufferPointer<UInt64>) -> String in
    let ubp = UnsafeRawBufferPointer(bp).bindMemory(to: UInt16.self)
    return String._uncheckedFromUTF16(ubp)

To follow up on that, I think from a memory binding perspective withMemoryRebound should be what you're looking for here:

let result = array.withUnsafeBufferPointer { (bp : UnsafeBufferPointer<UInt64>) -> String in
    return bp.withMemoryRebound(to: UInt16.self) {
1 Like

It did work.
Thank you!

Just for reference, I just minimize this sample created

Terms of Service

Privacy Policy

Cookie Policy