Repository: hylo-lang/hylo (swift)

Issue:
Interpret `_ = rhs` as a sugar for `let _ = rhs`
Everything is in the title.

Pull request description:
Closes https://github.com/hylo-lang/hylo/issues/977

- Returns `.let` as the introducer from `parseBindingIntroducer` when the current token is `_`

Patch:
diff --git a/Sources/FrontEnd/Parse/Parser.swift b/Sources/FrontEnd/Parse/Parser.swift
index 0e56cd7b8..a90622f29 100644
--- a/Sources/FrontEnd/Parse/Parser.swift
+++ b/Sources/FrontEnd/Parse/Parser.swift
@@ -2619,11 +2619,21 @@ public enum Parser {
         site: state.range(from: introducer.site.startIndex)))
   }
 
+  /// Parses a binding introducer.
+  ///
+  /// Should not be called before checking if the next token is `_` if another wildcard rule could apply.
   private static func parseBindingIntroducer(
     in state: inout ParserState
   ) throws -> SourceRepresentable<BindingPattern.Introducer>? {
     guard let head = state.peek() else { return nil }
 
+    // Interpret `_ = rhs` as a sugar for `let _ = rhs`
+    if head.kind == .under {
+      return SourceRepresentable(
+        value: .let,
+        range: state.lexer.sourceCode.emptyRange(at: state.currentIndex))
+    }
+
     let introducer: BindingPattern.Introducer
     switch head.kind {
     case .let:


Test patch:
diff --git a/Tests/EndToEndTests/TestCases/ExhaustiveBranchReturns.hylo b/Tests/EndToEndTests/TestCases/ExhaustiveBranchReturns.hylo
index 4775ef85d..eb1c39873 100644
--- a/Tests/EndToEndTests/TestCases/ExhaustiveBranchReturns.hylo
+++ b/Tests/EndToEndTests/TestCases/ExhaustiveBranchReturns.hylo
@@ -1,7 +1,7 @@
 //- compileAndRun expecting: success
 
 public fun main() {
-  let _ = f()
+  _ = f()
 }
 
 public fun f() -> Int {
diff --git a/Tests/HyloTests/ParserTests.swift b/Tests/HyloTests/ParserTests.swift
index 8662f323d..52181babf 100644
--- a/Tests/HyloTests/ParserTests.swift
+++ b/Tests/HyloTests/ParserTests.swift
@@ -1492,6 +1492,13 @@ final class ParserTests: XCTestCase {
     }
   }
 
+  func testLetSugarBindingPattern() throws {
+    let input: SourceFile = "_ = foo"
+    let (p, ast) = try input.parse(with: Parser.parseBindingPattern(in:))
+    let pattern = try XCTUnwrap(ast[p])
+    XCTAssertEqual(pattern.introducer.value, .let)
+  }
+
   func testBindingPatternWithAnnotation() throws {
     let input: SourceFile = "inout x: T)"
     let (p, ast) = try input.parse(with: Parser.parseBindingPattern(in:))