Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SR-6556] Sourcery source breakage: error: ambiguous use of 'trackDifference(actual:expected:)' #49106

Open
lplarson opened this issue Dec 7, 2017 · 17 comments
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 4.1 type checker Area → compiler: Semantic analysis

Comments

@lplarson
Copy link
Member

lplarson commented Dec 7, 2017

Previous ID SR-6556
Radar rdar://problem/37504986
Original Reporter @lplarson
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 4.1Regression, TypeChecker
Assignee @xedin
Priority Medium

md5: a7a0e42ecf3510a78ad35bf7c54853b1

relates to:

  • SR-7273 Sourcery source breakage: dependency on SourceKitten that uses IUOs in ways that are disallowed

Issue Description:

To reproduce:

  1. Install latest GM/Beta Xcode
  2. $ git clone git@github.com:apple/swift-source-compat-suite.git
  3. $ cd swift-source-compat-suite

To build Swift from scratch before testing:
4. $ ./reproduce.py master --project-path Sourcery --assertions

Or if you've already built Swift:
4. $ ./reproduce.py master --project-path Sourcery --assertions --swiftc path/to/swiftc

https://ci.swift.org/job/swift-PR-source-compat-suite-test-macOS/60/artifact/swift-source-compat-suite/FAIL_BuildSwiftPackage_Sourcery.log

/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:26:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "annotations").trackDifference(actual: self.annotations, expected: rhs.annotations))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:38:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "arguments").trackDifference(actual: self.arguments, expected: rhs.arguments))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:104:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "annotations").trackDifference(actual: self.annotations, expected: rhs.annotations))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:142:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "annotations").trackDifference(actual: self.annotations, expected: rhs.annotations))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:160:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "annotations").trackDifference(actual: self.annotations, expected: rhs.annotations))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:194:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "arguments").trackDifference(actual: self.arguments, expected: rhs.arguments))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:237:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "annotations").trackDifference(actual: self.annotations, expected: rhs.annotations))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.generated.swift:299:36: error: ambiguous use of 'trackDifference(actual:expected:)'
        results.append(contentsOf: DiffableResult(identifier: "annotations").trackDifference(actual: self.annotations, expected: rhs.annotations))
                                   ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:69:29: note: found this candidate
    @discardableResult func trackDifference<T: Equatable>(actual: T, expected: T) -> DiffableResult {
                            ^
/Users/buildnode/jenkins/workspace-private/swift-PR-source-compat-suite-test-macOS/project_cache/Sourcery/Sources/SourceryRuntime/Diffable.swift:166:29: note: found this candidate
    @discardableResult func trackDifference<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) -> DiffableResult {
                            ^
@belkadan
Copy link
Contributor

belkadan commented Dec 8, 2017

cc @rudkx, @xedin

@rudkx
Copy link
Member

rudkx commented Dec 8, 2017

Pavel, can you take a look at this?

I recall you made some changes related to ranking recently and I wonder if that caused this.

@xedin
Copy link
Member

xedin commented Dec 8, 2017

@rudkx This appears to be actually ambiguous if we account for Dictionary to be Equatable, here is the reduced example:

import Foundation

func foo<T: Equatable>(actual: T, expected: T) {}
func foo<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) {}

let x: [String: NSObject] = [:]
foo(actual: x, expected: x)

I think it might be due to the missing break in SolutionDiff I've fixed, but I think it's a legitimate problem which needs to be addressed by the project.

@xedin
Copy link
Member

xedin commented Dec 19, 2017

@DougGregor Can this actually be related to conditional conformances? Since I think @moiseev mentioned that dictionary is equatable how if the elements are.

@DougGregor
Copy link
Member

The second foo should be more specific, because you can use its parameters to call the first foo, but not vice-versa. It'd be interesting to know why that isn't working.

@xedin
Copy link
Member

xedin commented Dec 19, 2017

@DougGregor It looks like we currently don't have ranking rules for that (were they removed?):

Comparing 2 viable solutions
--- Solution #&#8203;0 ---
Fixed score: 0 0 0 0 0 0 0 0 0 0 0
Type variables:
  $T2 as [String : NSObject] @ locator@0x7f9caa523dc0 [DeclRef@<REPL Input>:1:26]
  $T9 as String @ locator@0x7f9caa524178 [OverloadedDeclRef@<REPL Input>:1:1 -> archetype 'T' -> archetype 'Key']
  $T10 as NSObject @ locator@0x7f9caa5241c8 [OverloadedDeclRef@<REPL Input>:1:1 -> archetype 'T' -> archetype 'Value']
  $T1 as [String : NSObject] @ locator@0x7f9caa523d40 [DeclRef@<REPL Input>:1:13]
  $T0 as ([String : NSObject], [String : NSObject]) -> () @ locator@0x7f9caa523c00 [OverloadedDeclRef@<REPL Input>:1:1]
  $T8 as [String : NSObject] @ locator@0x7f9caa523eb0 [OverloadedDeclRef@<REPL Input>:1:1 -> archetype 'T']

Overload choices:
  locator@0x7f9caa523dc0 [DeclRef@<REPL Input>:1:26] with REPL.(file).x@<REPL Input>:1:5 as x: [String : NSObject]

  locator@0x7f9caa523d40 [DeclRef@<REPL Input>:1:13] with REPL.(file).x@<REPL Input>:1:5 as x: [String : NSObject]

  locator@0x7f9caa523c00 [OverloadedDeclRef@<REPL Input>:1:1] with REPL.(file).foo(actual:expected:)@<REPL Input>:1:6 as foo: ($T8, $T8) -> ()


Constraint restrictions:
  Dictionary<String, NSObject> to Dictionary<String, NSObject> is [deep equality]

Disjunction choices:

Opened types:
  locator@0x7f9caa523c00 [OverloadedDeclRef@<REPL Input>:1:1] opens τ_0_0 -> $T8
--- Solution #&#8203;1 ---
Fixed score: 0 0 0 0 0 0 0 0 0 0 0
Type variables:
  $T2 as [String : NSObject] @ locator@0x7f9caa523dc0 [DeclRef@<REPL Input>:1:26]
  $T1 as [String : NSObject] @ locator@0x7f9caa523d40 [DeclRef@<REPL Input>:1:13]
  $T0 as ([String : NSObject], [String : NSObject]) -> () @ locator@0x7f9caa523c00 [OverloadedDeclRef@<REPL Input>:1:1]
  $T12 as NSObject @ locator@0x7f9caa5248a8 [OverloadedDeclRef@<REPL Input>:1:1 -> archetype 'T']
  $T11 as String @ locator@0x7f9caa524860 [OverloadedDeclRef@<REPL Input>:1:1 -> archetype 'K']

Overload choices:
  locator@0x7f9caa523dc0 [DeclRef@<REPL Input>:1:26] with REPL.(file).x@<REPL Input>:1:5 as x: [String : NSObject]

  locator@0x7f9caa523d40 [DeclRef@<REPL Input>:1:13] with REPL.(file).x@<REPL Input>:1:5 as x: [String : NSObject]

  locator@0x7f9caa523c00 [OverloadedDeclRef@<REPL Input>:1:1] with REPL.(file).foo(actual:expected:)@<REPL Input>:1:6 as foo: ([$T11 : $T12], [$T11 : $T12]) -> ()


Constraint restrictions:
  Dictionary<String, NSObject> to Dictionary<String, NSObject> is [deep equality]

Disjunction choices:

Opened types:
  locator@0x7f9caa523c00 [OverloadedDeclRef@<REPL Input>:1:1] opens τ_0_0 -> $T11, τ_0_1 -> $T12
comparing solutions 1 and 0
Comparing declarations
func foo<K, T>(actual: [K : T], expected: [K : T]) where K : Hashable, T : NSObjectProtocol {
}
and
func foo<T>(actual: T, expected: T) where T : Equatable {
}
Found cached comparison: 0
comparison result: not better
Comparing declarations
func foo<T>(actual: T, expected: T) where T : Equatable {
}
and
func foo<K, T>(actual: [K : T], expected: [K : T]) where K : Hashable, T : NSObjectProtocol {
}
Found cached comparison: 0
comparison result: not better
comparing solutions 0 and 1
Comparing declarations
func foo<T>(actual: T, expected: T) where T : Equatable {
}
and
func foo<K, T>(actual: [K : T], expected: [K : T]) where K : Hashable, T : NSObjectProtocol {
}
Found cached comparison: 0
comparison result: not better
Comparing declarations
func foo<K, T>(actual: [K : T], expected: [K : T]) where K : Hashable, T : NSObjectProtocol {
}
and
func foo<T>(actual: T, expected: T) where T : Equatable {
}
Found cached comparison: 0
comparison result: not better
comparing solutions 0 and 1
Comparing declarations
func foo<T>(actual: T, expected: T) where T : Equatable {
}
and
func foo<K, T>(actual: [K : T], expected: [K : T]) where K : Hashable, T : NSObjectProtocol {
}
Found cached comparison: 0
comparison result: not better
Comparing declarations
func foo<K, T>(actual: [K : T], expected: [K : T]) where K : Hashable, T : NSObjectProtocol {
}
and
func foo<T>(actual: T, expected: T) where T : Equatable {
}
Found cached comparison: 0
comparison result: not better

@rudkx
Copy link
Member

rudkx commented Dec 19, 2017

@xedin I believe you want to be looking at isDeclAsSpecializedAs.

@DougGregor
Copy link
Member

`isDeclAsSpecializedAs` is doing the right thing here, and the code is actually truly ambiguous due to the conditional conformance of `Dictionary` to `Equatable`. Neither of the two overloads in the reduced test case is more specialized than the other:

func foo<T: Equatable>(actual: T, expected: T) {}
func foo<K: Equatable, T: NSObjectProtocol>(actual: [K: T], expected: [K: T]) {}

because `NSObjectProtocol` is not `Equatable`. The backward- and forward-compatible fix here is to replace `NSObjectProtocol` with `NSObject`; once Swift 4.1 comes with its conditional conformances, the second overload can be removed entirely.

@belkadan
Copy link
Contributor

Is this still an issue?

@swift-ci
Copy link
Collaborator

Comment by Nicole Jacque (JIRA)

@swift-ci create

@lplarson
Copy link
Member Author

@DougGregor/@xedin Does this issue require a project change?

@xedin
Copy link
Member

xedin commented Feb 13, 2018

@lplarson It seems to me that it would be required yes, but @DougGregor is a better person to reply to that...

@lplarson
Copy link
Member Author

Reached out to project maintainer requesting a hash update containing a fix.

@swift-ci
Copy link
Collaborator

Comment by Krzysztof Zabłocki (JIRA)

Should be fixed on Master, via commit: 3041ba7ed84138f13e7973d34973dce2b10259be

@lplarson
Copy link
Member Author

merowing (JIRA User), thanks! Please open a PR on the swift-source-compat-suite projects.json file updating the project hash.

@lplarson
Copy link
Member Author

Hash update PR merged.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 4.1 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

7 participants