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-13240] non-specific diagnostic when calling a function with two wrong-type arguments #55681

Closed
marcrasi mannequin opened this issue Jul 17, 2020 · 12 comments
Closed
Assignees
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation regression swift 5.3 type checker Area → compiler: Semantic analysis

Comments

@marcrasi
Copy link
Mannequin

marcrasi mannequin commented Jul 17, 2020

Previous ID SR-13240
Radar rdar://problem/65842034
Original Reporter @marcrasi
Type Bug
Status Closed
Resolution Done
Environment

swift-DEVELOPMENT-SNAPSHOT-2020-07-14-a-ubuntu20.04

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 5.3Regression, DiagnosticsQoI, TypeChecker
Assignee @LucianoPAlmeida
Priority Medium

md5: d23f6c9602953bf690f36dffaa470bb3

Issue Description:

func twoargs(_ x: String, _ y: String) {}

func test() {
  let x = 1

  // Actual diagnostic:
  //   error: type of expression is ambiguous without more context
  //   twoargs(x, x)
  //   ^~~~~~~~~~~~~
  //
  // Desired diagnostic:
  //   error: cannot convert value of type 'Int' to expected argument type 'String'
  //   twoargs(x, x)
  //           ^
  //
  //   error: cannot convert value of type 'Int' to expected argument type 'String'
  //   twoargs(x, x)
  //              ^
  twoargs(x, x)
}
@theblixguy
Copy link
Collaborator

cc @xedin @hborla looks like a regression since 5.2. It seems like we have a failed constraint (argument conversion from Int to String) in the system and so salvage() bails out when it sees it and we don't end up actually solving the system in salvage mode.

@LucianoPAlmeida
Copy link
Collaborator

This problem seems to be related to this early return on CSSimplify

where we have a single overload choice and two arg to param constraint failures where the second one is not "diagnose" let the solver is unable to form a solution for that, therefore leading to an ambiguous diagnostic ... @xedin, initially I thought that only consider this "fixed" and just return as diagnosed would be able to handle this, but the reality is that this being as it is important for a lot of diagnostics

@LucianoPAlmeida
Copy link
Collaborator

This also leads to ambiguous diagnostics in situations like

infix operator ---
 
func --- (_ lhs: String, _ rhs: String) -> Bool {
  return true
}
let x = 1
 
x --- x // type of expression is ambiguous without more context

It is basically the same case

@theblixguy
Copy link
Collaborator

IIRC you get a diagnostic if you have two different variables (x and y) so it seems like this only happens when you have >1 failure associated with the same argument?

@LucianoPAlmeida
Copy link
Collaborator

Do you mean like

func twoargs(_ x: String, _ y: String) {}

func test() {
  let x = 1
  let y = 1

  twoargs(x, y) // type of expression is ambiguous without more context
}

infix operator ---

func --- (_ lhs: String, _ rhs: String) -> Bool {
  return true
}
let x = 1
let y = 1

x --- y // type of expression is ambiguous without more context

In this case, we still get ambiguous for the same reason, the problem is when having more than one argument failure (for any argument) e.g. in those cases args #0 and #1 fail on the same call anchor. I really don't know what would be an approach to solve this, as the comment in line 3644 states ("we can consider overload unrelated"), but this leads to problems like those examples here if all overloads are ignored ... and change this would impact a lot of other diagnostics.
Maybe we could change this to return this as diagnosed, and implement a custom logic on `ArgumentFix::diagnoseAmbiguity`... not really sure

@theblixguy
Copy link
Collaborator

Oh sorry, I think I got confused when I was testing out a few other cases. I thought I remembered seeing a diagnostic when using different variables instead of the same one.

@xedin
Copy link
Member

xedin commented Jul 20, 2020

I think it might work to start recording all of the argument failures and increase a score significantly after each one to indicate that the more argument are mismatching the least desirable this overload choice is...

@LucianoPAlmeida
Copy link
Collaborator

@xedin I've seen that there is already a score increasing for argument fix here

increaseScore(SK_Fix);
so in that case this should be increased even more or just remove this check and record them all should be sufficient to handle this?

@xedin
Copy link
Member

xedin commented Jul 22, 2020

@LucianoPAlmeida I'm taking about this bit

swift/lib/Sema/CSSimplify.cpp

Lines 3643 to 3657 in 506aa1d

// If there are any other argument mismatches already detected
// for this call, we can consider overload unrelated.
if (llvm::any_of(getFixes(), [&](const ConstraintFix *fix) {
auto *locator = fix->getLocator();
// Since arguments to @dynamicCallable form either an array
// or a dictionary and all have to match the same element type,
// let's allow multiple invalid arguments.
if (locator->findFirst<LocatorPathElt::DynamicCallable>())
return false;
return locator->findLast<LocatorPathElt::ApplyArgToParam>()
? locator->getAnchor() == anchor
: false;
}))
break;
- `repairFaiures` rejects to fix more than one argument (if it finds multiple failures in a single component), I think we need to actually switch that to record a fix and increase a score even higher, so this logic should go to
increaseScore(SK_Fix);
instead.

@LucianoPAlmeida
Copy link
Collaborator

Right @xedin let's try that!

@LucianoPAlmeida
Copy link
Collaborator

Fixed on master @marcrasi can you please test on the next available snapshot? thanks

@marcrasi
Copy link
Mannequin Author

marcrasi mannequin commented Aug 14, 2020

I verified it. Thanks!!

@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 diagnostics QoI Bug: Diagnostics Quality of Implementation regression swift 5.3 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

4 participants