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-13706] Fix-it for missing let/var in pattern when identifier is unbound #56103

Open
kavon opened this issue Oct 8, 2020 · 2 comments
Open
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-13706
Radar rdar://problem/70075206
Original Reporter @kavon
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, DiagnosticsQoI, TypeChecker
Assignee None
Priority Medium

md5: 7687cfd33e3fca67b424828244e645ce

relates to:

  • SR-13707 Fix-it for missing let/var in ill-typed expression pattern

Issue Description:

The problem with this code:

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

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

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

is that the programmer forgot to write `case let` or `case var` to introduce a new binding in the pattern for Cons. Because of this, the compiler interpreted it as an expression pattern and reports:

missing_let_int.swift:9:20: error: cannot find 'hd' in scope
        case .Cons(hd, _): return hd
                   ^~
missing_let_int.swift:9:35: error: cannot find 'hd' in scope
        case .Cons(hd, _): return hd
                                  ^~

I think it would be helpful to have a fix-it suggesting that they add a let / var, since no `hd` exists in the scope.

In some situations, this fix-it should not be emitted, such as:

switch (1, 2) {
  case (var a, a): ()
}

where a suggestion to add 'let' or 'var' for the second sub-pattern in the tuple will introduce an invalid redeclaration of 'a'. In this next situation, a different fix-it would be better for the two unbound identifiers:

enum Color {
  case gray
}

let x : Color? = nil
switch x {
  case none: ()
  case .some(gray): ()
}

Based on the type of the switch's scrutinee and the patterns themselves, a better fix-it would be to suggest adding a dot in front of `none` and `gray`. This way, they'll refer to their respective enums (Optional<T> and Color) because their names match one of the enums variants exactly. The better fix-it is most likely what the programmer intended instead of introducing a new binding.

@typesanitizer
Copy link

@swift-ci create

@kavon
Copy link
Contributor Author

kavon commented Oct 9, 2020

I took a crack at this but the implementation emitted the fix-it in incorrect situations: #34242

I'm not currently able to devote more time to this.

@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