Repository: hylo-lang/hylo (swift)

Issue:
Errors in the inference of an overloaded argument generates bad diagnostics
If I compile this code:

```
public fun main()
{
  let numbers: Int[2] = [1, 2]
  print(numbers[0])
}
```

I get this error:

```
     main.hylo:4.3-8: error: ambiguous use of 'print'
       print(numbers[0])
       ~~~~~
     /Users/david/Developer/hylo/StandardLibrary/Sources/Print.hylo:9.1-32:2: note: candidate here
     public fun print(_ item: Int, radix: Int = 10, terminator: String = "\n") {
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     /Users/david/Developer/hylo/StandardLibrary/Sources/Print.hylo:2.1-6:2: note: candidate here
     public fun print(_ item: String, terminator: String = "\n") {
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```

Possibly related to issue #1526, that the subscript isn't recognized.

I'm using Hylo on a MacBook Pro with M1 Pro, compiled from this commit: f6ee33caaf9c96f8c03aa79d2e8381debdc6dd5a

Pull request:
Keep diagnostics that are common to all solutions when an ambiguity is detected during constraint solving.

Patch:
diff --git a/Sources/FrontEnd/DiagnosticSet.swift b/Sources/FrontEnd/DiagnosticSet.swift
index d08ce0625..d02d01df2 100644
--- a/Sources/FrontEnd/DiagnosticSet.swift
+++ b/Sources/FrontEnd/DiagnosticSet.swift
@@ -33,6 +33,11 @@ public struct DiagnosticSet: Error {
     containsError = containsError || other.containsError
   }
 
+  /// Removes from `self` the elements that are not also contained in `other`.
+  public mutating func formIntersection(_ other: Self) {
+    self = .init(elements.filter(other.elements.contains(_:)))
+  }
+
   /// Throws `self` if any errors were reported.
   public func throwOnError() throws {
     if containsError { throw self }
diff --git a/Sources/FrontEnd/TypeChecking/ConstraintSystem.swift b/Sources/FrontEnd/TypeChecking/ConstraintSystem.swift
index 9d520da28..fefdab245 100644
--- a/Sources/FrontEnd/TypeChecking/ConstraintSystem.swift
+++ b/Sources/FrontEnd/TypeChecking/ConstraintSystem.swift
@@ -192,11 +192,17 @@ struct ConstraintSystem {
       penalties: penalties, diagnostics: d, stale: stale.map({ goals[$0] }))
   }
 
-  /// Creates an ambiguous solution.
+  /// Creates an ambiguous solution, reporting the ambiguity with `d`.
+  ///
+  /// The return value is the intersection of the choices and diagnostics that are identical in
+  /// each result along with an additional diagnostic describing the ambiguity.
+  ///
+  /// - Requires: `result` contains at least two elements.
   private func formAmbiguousSolution<T>(
     _ results: Explorations<T>, diagnosedBy d: Diagnostic
   ) -> Solution {
-    var s = results.elements.reduce(into: Solution(), { (s, r) in s.formIntersection(r.solution) })
+    let (first, others) = results.elements.headAndTail!
+    var s = others.reduce(into: first.solution, { (s, r) in s.formIntersection(r.solution) })
     s.incorporate(d)
     return s
   }
diff --git a/Sources/FrontEnd/TypeChecking/Solution.swift b/Sources/FrontEnd/TypeChecking/Solution.swift
index 2a5febeaa..970c6a173 100644
--- a/Sources/FrontEnd/TypeChecking/Solution.swift
+++ b/Sources/FrontEnd/TypeChecking/Solution.swift
@@ -83,6 +83,7 @@ struct Solution {
   mutating func formIntersection(_ other: Self) {
     typeAssumptions.formIntersection(other.typeAssumptions)
     bindingAssumptions.formIntersection(other.bindingAssumptions)
+    diagnostics.formIntersection(other.diagnostics)
     penalties = max(penalties, other.penalties)
   }
 


Test patch:
diff --git a/Tests/HyloTests/TestCases/TypeChecking/Overloading.hylo b/Tests/HyloTests/TestCases/TypeChecking/Overloading.hylo
index be45f81ed..1a5a0f705 100644
--- a/Tests/HyloTests/TestCases/TypeChecking/Overloading.hylo
+++ b/Tests/HyloTests/TestCases/TypeChecking/Overloading.hylo
@@ -39,5 +39,5 @@ public fun main() {
   check<Any>(x6)
 
   let a = 1
-  fn(a, a)    //! diagnostic ambiguous use of 'fn'
+  _ = fn(a, a) //! diagnostic ambiguous use of 'fn'
 }