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-15746] Incorrect expected argument type displayed in error message #58023

Open
AnthonyLatsis opened this issue Jan 18, 2022 · 4 comments
Open
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself type checker Area → compiler: Semantic analysis

Comments

@AnthonyLatsis
Copy link
Collaborator

Previous ID SR-15746
Radar None
Original Reporter @AnthonyLatsis
Type Bug
Environment

Swift version 5.6-dev (LLVM 7b20e61dd04138a, Swift ab0577a91f0b152)

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

md5: b54a35bf020183fecb5284cf34b550ce

Issue Description:

protocol P {}
class Class {}

func foo<U>(_: U) where U: P & Class {}

do {
  // error: global function 'foo' requires that 'Class' conform to 'P'
  // error: cannot convert value of type 'Bool' to expected argument type 'Class'
  foo(false)
}
@kavon
Copy link
Contributor

kavon commented Jan 20, 2022

I guess the specific incorrect error message is the one that says
global function 'foo' requires that 'Class' conform to 'P'
because there are other ways to satisfy the constraint without making the Class conform to P? For example:

protocol P {}
class ClassA {}
class ClassB: ClassA, P {}

func foo<U>(_: U) where U: ClassA & P {}

func test(x: ClassB) {  
  foo(x) // OK
  foo(true) // error: global function 'foo' requires that 'ClassA' conform to 'P'      // ^ not the only way to satisfy the constraint.
}

@AnthonyLatsis
Copy link
Collaborator Author

The "cannot convert" error message shouldn't be emitted at all, since there is no concrete expected argument type – it's a generic parameter. The requirement failure message should instead say global function 'foo' requires that 'Bool' conform to 'P' or global function 'foo' requires that 'Bool' inherit from 'Class', because the substitution for U in foo(false) is Bool, not Class. This issue disappears if we remove either the Class or P constraint on foo.

@kavon
Copy link
Contributor

kavon commented Jan 20, 2022

I see what you mean. When removing the `& P` from the constraint, the message accurately says "global function 'foo' requires that 'Bool' inherit from 'Class'", but when it's there, the error about Bool not being a subtype of Class is now phrased in terms of a conversion failure.

Since type conversions are done automatically via subtyping (among other avenues), being more specific about why the automatic conversion failed, i.e., that it doesn't inherit, would be better.

@AnthonyLatsis
Copy link
Collaborator Author

Yeah. It appears as if we inadvertently skip recording the requirement failure fix for the primary substitute (Bool in this case) when there's both a conformance and superclass constraint, perhaps causing the U := Class binding to be attempted to salvage the system, hence the misleading automatic conversion failure.

@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 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants