Skip to content

Move tuple heuristic on patterns to the typer

E. Rivas requested to merge er433/fix/tuple-heuristic-on-func into dev

Motivation and Context

Xavier reported a bug on the following JsLIGO snippet:

const f = ([] : unit) : int => 42

due to the heuristics in pattern matching which are not great:

Invalid type(s)
Cannot unify "list (^a)" with "unit".
Hint: "^a" represent placeholder type(s).

Description

This MR proposes to move the heuristics for pattern matching to the typer.

Changes:

  • rename P_tuple_with_ellipsis to P_array to be consistent with expressions, and re-use Array_repr.
  • use a decorator on patterns (which is identity on ast-typed, and kept a bool in ast-core).
  • add a P_typed on Pattern.t: it is only inhabited on ast-core, for ast-typed/ast-aggregated is the empty type.
  • removed List ... pattern for using directly Nil, as it didn't work in the typer before anyway.
  • implement the heuristic logic in infer_tuple_pattern, it has basically four cases:
    • the tuple is [] and it is a single clause pattern: it is understood as a pattern on unit.
    • the tuple is [] and it is a non-single clause pattern: it is understood as a pattern on empty list.
    • the tuple has the form [x1, ..., xn, ...xs]: it is understood as a pattern on a list.
    • in other cases: it is understood as a pattern on a tuple.

Example:

const f = ([] : unit) : unit => [];
const g = ([]) : unit => []; // unit => unit
const h = (l) => match (l) { when([]): 42; } // unit => int
const i = (l : unit) => match (l) { when([]): 42; }
const j = (l) => match (l) { when([]): 42; default: 0; } // list<a> => int
const k = (l : list<int>) => match (l) { when([]): 42; default: 0; }

Component

  • compiler
  • website
  • webide
  • vscode-plugin
  • debugger

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Performance improvement (non-breaking change that improves performance)
  • None (change with no changelog)

Changelog

Checklist:

  • If a new syntax has been introduced, put a message on slack ligo-lsp
  • Changes follow the existing coding style (use dune @fmt to check).
  • Tests for the changes have been added (for bug fixes / feature).
  • Documentation has been updated.
  • Changelog description has been added (if appropriate).
  • Start titles under ## Changelog section with #### (if appropriate).
  • There is no image or uploaded file in changelog
  • Examples in changed behaviour have been added to the changelog (for breaking change / feature).
Edited by E. Rivas

Merge request reports