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-11367] Misleading error message with type errors inside a closure #53768

Open
swift-ci opened this issue Aug 23, 2019 · 4 comments
Open

[SR-11367] Misleading error message with type errors inside a closure #53768

swift-ci opened this issue Aug 23, 2019 · 4 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-11367
Radar rdar://problem/54771408
Original Reporter apaszke (JIRA User)
Type Bug
Environment

Apple Swift version 5.1 (swiftlang-1100.0.257.2 clang-1100.0.31.3)

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

md5: ae43068899072811621c00229f5a7440

Issue Description:

Consider this piece of code:

public typealias VarName = String

public struct Var: Hashable {
  let name: VarName
}

public enum BoolExpr {
  case literal(Bool)
}

public enum Expr {
  case bool(BoolExpr)
}

public typealias Substitution = (VarName) -> VarName

public func substitute(_ e: BoolExpr, using s: Substitution) -> BoolExpr {
    return e
}

public func substitute(_ c: Expr, using s: Substitution) -> Expr {
    return c
}

class X {
  func apply(_ generic: Expr) {
    var substitution = [Var: Var]()
    var results: [Expr] = []
    switch generic {
    case let .bool(expr):
      results.append(substitute(expr, using: { substitution[$0] }))
    }
  }
}

It contains a type error because the $0 in substitution[$0] is of type VarName, while substitution maps {{Var}}s to {{Var}}s. However, the compiler reports it as:

error.swift:31:33: error: cannot convert value of type 'BoolExpr' to expected argument type 'Expr'
      results.append(substitute(expr, using: { substitution[$0] }))
                                ^~~~

which does not make sense, given that there is an overload for BoolExpr.


While trying to minimize this example I've also hit another likely related issue. To reproduce this one replace the class X definition in the program above with this:

struct DefaultDict<K : Hashable, V> {
  var dict: [K: V] = [:]
  let def: V

  init(_ def: V) { self.def = def }

  subscript(_ key: K) -> V {
    mutating get {
      if dict[key] == nil { dict[key] = def }
      return dict[key]!
    }
  }
}

func error() {
    let x = Var(name: "asdf")
    var lookup = DefaultDict<Var,Var>(x)
    print(lookup[x])
    substitute(BoolExpr.literal(false), using: { lookup[$0] })
}

This program suffers from the same type error as the original one, but the reported failure is now:

error2.swift:43:56: error: value of type 'DefaultDict<Var, Var>' has no subscripts
    substitute(BoolExpr.literal(false), using: { lookup[$0] })
                                                 ~~~~~~^~~~

which is again obviously false given that print(lookup[x]) type checks successfully.

@theblixguy
Copy link
Collaborator

results.append(substitute(expr, using: { substitution[$0] }))

1. The signature of substitute here is (BoolExpr, Substitution) -> BoolExpr, but you're trying to add the returned value to an array of type [Expr]. To fix this, what you need is another method of type (BoolExpr, Substitution) -> Expr or change the type of the array to be [BoolExpr].

2. You also have another error on the same line: substitution[$0]. This is incorrect because the type of substitution is [Var: Var] (where Var = struct Var), where as you're trying to subscript it with $0 which is a VarName (a typealias for String), because Substitution is a typealias for (VarName) -> VarName.

substitute(BoolExpr.literal(false), using: { lookup[$0] })

3. This has the same problem as (2) above. The type of $0 here is VarName (where VarName = String).

@theblixguy
Copy link
Collaborator

Although I agree the diagnostics can be improved in this case. cc @xedin

@swift-ci
Copy link
Collaborator Author

Comment by Adam Paszke (JIRA)

Look, I agree this code is incorrect, and it has been indicated in the issue title as well... My point is that both error messages I'm getting are completely false and do not direct me to the real cause of failure.

The snippets I've pasted here are a minimal version of the code I was writing in a real application, and I kept minimizing them until those particular errors disappeared, so I might have introduced extra type errors in the process. Thanks for catching them, but I feel like this only highlights how bad the error message is, given how many real type errors there are 🙂

@xedin
Copy link
Member

xedin commented Aug 28, 2019

@swift-ci create

@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
Projects
None yet
Development

No branches or pull requests

3 participants