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-7940] "Ambiguous use" in Xcode 10, Swift 4.2 #50475

Closed
swift-ci opened this issue Jun 9, 2018 · 8 comments
Closed

[SR-7940] "Ambiguous use" in Xcode 10, Swift 4.2 #50475

swift-ci opened this issue Jun 9, 2018 · 8 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 4.2 type checker Area → compiler: Semantic analysis

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jun 9, 2018

Previous ID SR-7940
Radar rdar://problem/40970309
Original Reporter AntonSchukin (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Xcode 10 beta (10L176w)
Swift 4.2

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 4.2Regression, TypeChecker
Assignee None
Priority Medium

md5: 55eeb487df67c567d097cb4bc9282854

is duplicated by:

  • SR-8343 Protocol Ambiguity with Swift 4.2 (Xcode 10b4)

Issue Description:

In Xcode 10 code in the attached playground compiling with error "Ambiguous use of ...".

A diagnostic report doesn't contain much information. A compiler produces an error when an object type is a combination of class and protocol types and a property of that object that is declared in both types is accessed.

Not sure is it a bug or intentional change. It worked before in Xcode 9.3 and Swift 4.1

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jun 9, 2018

Comment by Anton Schukin (JIRA)

@bob-wilson Thank you for your help on the lab session.

@bob-wilson
Copy link

You're welcome – thank you for the bug report

@bob-wilson
Copy link

@swift-ci create

@slavapestov
Copy link
Member

In Swift 4.2 some of the rules around ambiguous member references were tightened up. Note that in 4.1, it was already ambiguous to reference a method in this manner:

amb.swift:12:3: error: ambiguous use of 'function()'
  t.function()
  ^
amb.swift:3:8: note: found this candidate
  func function() {}
       ^
amb.swift:8:8: note: found this candidate
  func function()
       ^

If the class already provides the requirements of the protocol, you should make the class conform to the protocol, and not use a subclass existential. Only use a subclass existential if the class does not actually implement the protocol.

@swift-ci
Copy link
Collaborator Author

Comment by Anton Schukin (JIRA)

@slavapestov So, basically, if a protocol defines a function or variable that matches a function or variable from existential class I have no other choice but make this class conform to the protocol and provide default implementation and then override it in subclasses. This way doesn't give necessary compile time checks as you may forget to override default implementation. Before compiler guaranteed that I can't put an object of a base class (because it doesn't conform to a protocol) or subclass that doesn't conform to a protocol into a variable. So, I could only put an object of a subclass that conforms to a protocol.

Consider next example with protocols:

protocol Protocol {
    func function()
}

protocol AnotherProtocol {
    func function()
}

class Impl: AnotherProtocol, Protocol {
    func function() {}
}

var t: AnotherProtocol & Protocol = Impl()
t.function()

This code doesn't produce an error. For me those two cases are similar and I would expect the same behaviour.

@slavapestov
Copy link
Member

> So, basically, if a protocol defines a function or variable that matches a function or variable from existential class I have no other choice but make this class conform to the protocol and provide default implementation and then override it in subclasses.

Either the class provides implementations of those requirements, in which case it conforms to the protocol, or it doesn't, in which case you don't need to provide a default either.

> This code doesn't produce an error. For me those two cases are similar and I would expect the same behaviour.

The ambiguity was already diagnosed in 4.1 for methods; the new behavior in 4.2 is more consistent, just not in the direction you expect. Suppose both the protocol and the class define a method with the same name; which one would you expect member access to pick on a subclass existential value, and why?

@swift-ci
Copy link
Collaborator Author

Comment by Anton Schukin (JIRA)

@slavapestov

Either the class provides implementations of those requirements, in which case it conforms to the protocol, or it doesn't, in which case you don't need to provide a default either.

In the second case I have a compilation error as in the example due to a variable with the same name in a protocol and in a base class. I would like to add that a protocol may contain more variables that don't overlap with variables from a base class and exist only in subclasses that conforms to the protocol.

Suppose both the protocol and the class define a method with the same name; which one would you expect member access to pick on a subclass existential value, and why?

I thought that "MyClass & MyProtocol" declaration means "any MyClass that conforms to MyProtocol". So a type with this declaration already adopts MyProtocol (either through .extension to MyClass or in subclasses). In this way I see no ambuigity. But I suppose that I don't see the whole picture and I may be wrong about it.

@swift-ci
Copy link
Collaborator Author

Comment by Anton Schukin (JIRA)

@slavapestov I checked another example, with generics. It also have an ambiguous error:

class Class {
    let property: Int = 0
}

protocol Protocol {
    var property: Int { get }
}

class Generic<T> where T: Class, T: Protocol {
    var a: T
    init(a: T) {
        print(a.property)
    }
}

I suppose, this is expected. Thank you for clarification.

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
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.2 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants