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-13707] Fix-it for missing let/var in ill-typed expression pattern #56104

Open
kavon opened this issue Oct 8, 2020 · 1 comment
Open

[SR-13707] Fix-it for missing let/var in ill-typed expression pattern #56104

kavon opened this issue Oct 8, 2020 · 1 comment
Labels
compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation improvement type checker Area → compiler: Semantic analysis

Comments

@kavon
Copy link
Contributor

kavon commented Oct 8, 2020

Previous ID SR-13707
Radar rdar://problem/70075207
Original Reporter @kavon
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, DiagnosticsQoI, TypeChecker
Assignee None
Priority Medium

md5: 56d9c5d34022ff4984c7e5bdb640d5e2

relates to:

  • SR-13706 Fix-it for missing let/var in pattern when identifier is unbound

Issue Description:

Consider this incorrect code:

enum List {
    indirect case Cons(Int, List)
    case Nil
}

func hd(_ lst : List) -> Int? {
    switch lst {
        case .Cons(hd, _): return hd
        case .Nil: return nil
    }
}

let lst = List.Cons(1, List.Nil)
if let h = hd(lst) {
    print(h)
}

The programmer (me) thought they were introducing a new binding, `hd` in the Cons case pattern. But, that requires a let/var in the pattern, so the compiler interprets it as an expression pattern. Not to be confused with SR-13706, here `hd` is bound as the name of the function itself, so we get the following type error:

missing_let_int.swift:9:20: error: expression pattern of type '(List) -> Int?' cannot match values of type 'Int'
        case .Cons(hd, _): return hd
                   ^~
missing_let_int.swift:9:35: error: cannot convert return expression of type '(List) -> Int?' to return type 'Int?'
        case .Cons(hd, _): return hd
                                  ^~

In this case, a fix-it may be warranted to suggest that they add a let/var in the pattern. The errors can get quite nasty and confusing when making this mistake for a more complex enum type, such as in this code:

enum List<T> {
    indirect case Cons(T, List<T>)
    case Nil
}

func hd<T>(_ lst : List<T>) -> T? {
    switch lst {
        case .Cons(hd, _): return hd
        case .Nil: return nil
    }
}

let lst = List.Cons(1, List.Nil)
if let h = hd(lst) {
    print(h)
}

Which gives all of these errors:

missing_let.swift:9:20: error: expression pattern of type '(List<T>) -> T?' cannot match values of type 'T'
        case .Cons(hd, _): return hd
                   ^~
missing_let.swift:9:20: error: generic parameter 'T' could not be inferred
        case .Cons(hd, _): return hd
                   ^
missing_let.swift:7:6: note: in call to function 'hd'
func hd<T>(_ lst : List<T>) -> T? {
     ^
missing_let.swift:9:35: error: cannot convert return expression of type '(List<T>) -> T?' to return type 'T?'
        case .Cons(hd, _): return hd
                                  ^~
                                     as! T
missing_let.swift:9:35: error: generic parameter 'T' could not be inferred
        case .Cons(hd, _): return hd
                                  ^
missing_let.swift:7:6: note: in call to function 'hd'
func hd<T>(_ lst : List<T>) -> T? {
     ^

theindigamer (JIRA User) agrees that a fix-it may be good here.

@typesanitizer
Copy link

@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
compiler The Swift compiler in itself diagnostics QoI Bug: Diagnostics Quality of Implementation improvement type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

2 participants