swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67k stars 10.32k forks source link

[Source Compatibility] Custom loadUnaligned function ambiguous, fails to compile in Swift 6.0 #74347

Open karwa opened 1 month ago

karwa commented 1 month ago

Description

No response

Reproduction

extension UnsafeRawPointer {

    // backported version of `loadUnaligned`
    internal func loadUnaligned<T>(
        fromByteOffset offset: Int = 0,
            as: T.Type
    ) -> T where T: FixedWidthInteger {
        fatalError("stub")
    }
}

extension UnsafeBufferPointer<UInt8> {

    func test() {
        let _ = UnsafeRawPointer(self.baseAddress!)
          .loadUnaligned(as: UInt64.self)
    }
}

Stable versions of the compiler accept this code. However, the Swift 6.0 compiler (nightlies, and Xcode 16.0 beta) fail to compile it, complaining that there is some ambiguous use of init:

<source>:13:17: error: ambiguous use of 'init(_:)'
11 | 
12 |     func test() {
13 |         let _ = UnsafeRawPointer(self.baseAddress!)
   |                 `- error: ambiguous use of 'init(_:)'
14 |           .loadUnaligned(as: UInt64.self)
15 |     }

Swift.UnsafeRawPointer:2:12: note: found this candidate in module 'Swift'
1 | extension UnsafeRawPointer {
2 |     public init<T>(_ other: UnsafePointer<T>) where T : ~Copyable
  |            `- note: found this candidate in module 'Swift'
3 |     public init?<T>(_ other: UnsafePointer<T>?) where T : ~Copyable
4 | }

Swift._Pointer:6:12: note: found this candidate in module 'Swift'
4 |     public init?(bitPattern: Int)
5 |     public init?(bitPattern: UInt)
6 |     public init(_ other: Self)
  |            `- note: found this candidate in module 'Swift'
7 |     public init?(_ other: Self?)
8 | }
Compiler returned: 1

This message appears to be incorrect - commenting out the backported loadUnaligned resolves the error (because the newer stdlib has its own version of loadUnaligned, the call is still valid). There doesn't seem to be anything ambiguous about the initialiser.

Expected behavior

Expect it to compile.

Environment

Swift version 6.0-dev (LLVM 579155491d559cc, Swift 64869e5a42221b2) Target: x86_64-unknown-linux-gnu

Also Xcode 16.0 beta (16A5171c)

Additional information

This was reported by users of my package: https://github.com/karwa/swift-url/issues/186

[Godbolt](https://swift.godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:swift,selection:(endColumn:2,endLineNumber:8,positionColumn:2,positionLineNumber:8,selectionStartColumn:2,selectionStartLineNumber:8,startColumn:2,startLineNumber:8),source:'extension+UnsafeRawPointer+%7B%0A++++internal+func+loadUnaligned%3CT%3E(%0A++++++++fromByteOffset+offset:+Int+%3D+0,%0A++++++++++++as:+T.Type%0A++++)+-%3E+T+where+T:+FixedWidthInteger+%7B%0A++++++++fatalError(%22stub%22)%0A++++%7D%0A%7D%0A%0Aextension+UnsafeBufferPointer%3CUInt8%3E+%7B%0A%0A++++func+test()+%7B%0A++++++++let+_+%3D+UnsafeRawPointer(self.baseAddress!!)%0A++++++++++.loadUnaligned(as:+UInt64.self)%0A++++%7D%0A%7D'),l:'5',n:'1',o:'Swift+source+%231',t:'0')),k:33.83812010443865,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:swiftnightly,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'0',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:swift,libs:!(),options:'-O',overrides:!(),selection:(endColumn:45,endLineNumber:3,positionColumn:45,positionLineNumber:3,selectionStartColumn:45,selectionStartLineNumber:3,startColumn:45,startLineNumber:3),source:1),l:'5',n:'0',o:'+x86-64+swiftc+nightly+(Editor+%231)',t:'0')),k:32.82854656222803,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:output,i:(compilerName:'x86-64+swiftc+5.10',editorid:1,fontScale:14,fontUsePx:'0',j:1,wrap:'1'),l:'5',n:'0',o:'Output+of+x86-64+swiftc+nightly+(Compiler+%231)',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:'0',o:'',t:'0')),version:4) shows that the error occurs on nightly (at least, for the nightly that it currently has -- listed in the Environment section), but not on 5.10 or previous releases.

karwa commented 1 month ago

And actually, you can get a similar error just with a plain use of loadUnaligned, no initialisers or anything:

extension UnsafeRawPointer {

    // backported version of `loadUnaligned`
    internal func loadUnaligned<T>(
        fromByteOffset offset: Int = 0,
            as: T.Type
    ) -> T where T: FixedWidthInteger {
        fatalError("stub")
    }
}

extension UnsafeRawPointer {

    func test() {
        let _ = loadUnaligned(as: UInt64.self)
    }
}
<source>:13:17: error: ambiguous use of 'loadUnaligned(fromByteOffset:as:)'
 1 | extension UnsafeRawPointer {
 2 |     internal func loadUnaligned<T>(
   |                   `- note: found this candidate 
 3 |         fromByteOffset offset: Int = 0,
 4 |             as: T.Type
   :
11 | 
12 |     func test() {
13 |         let _ = loadUnaligned(as: UInt64.self)
   |                 `- error: ambiguous use of 'loadUnaligned(fromByteOffset:as:)'
14 |     }
15 | }

Swift.UnsafeRawPointer:10:28: note: found this candidate in module 'Swift'
 8 |     public func assumingMemoryBound<T>(to: T.Type) -> UnsafePointer<T> where T : ~Copyable
 9 |     @inlinable public func load<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T
10 |     @inlinable public func loadUnaligned<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T where T : BitwiseCopyable
   |                            `- note: found this candidate in module 'Swift'
11 |     @inlinable public func loadUnaligned<T>(fromByteOffset offset: Int = 0, as type: T.Type) -> T
   |                            `- note: found this candidate in module 'Swift'
12 | }
Compiler returned: 1