unison/unison-src/transcripts-using-base/fix4746.output.md
2024-04-14 20:20:36 -04:00

1.3 KiB

Test case for a variable capture problem during let floating. The encloser wasn't accounting for variables bound by matches.

ability Issue t where
  one : '{Issue t} () -> {Issue t} ()
  two : '{Issue t} () -> {Issue t} ()
  three : '{Issue t} () -> {Issue t} ()

x : '{Issue t} () -> {Issue t} ()
x _ = ()

works x = x + 1

run : '{Issue t} () -> '{Stream Text} ()
run s =
  go = cases
    { one x -> resume } ->
      emit "one"
      handle resume !x with go
    { two x -> resume } ->
      emit "two"
      handle resume !x with go
    { three x -> resume } ->
      emit "three"
      handle resume !x with go
    { _ } -> emit "done"
  do handle !s with go

> Stream.toList <| run do
  Issue.one do
    Issue.two do
      ()
    Issue.three do
      ()

  Loading changes detected in scratch.u.

  I found and typechecked these definitions in scratch.u. If you
  do an `add` or `update`, here's how your codebase would
  change:
  
    ⍟ These new definitions are ok to `add`:
    
      ability Issue t
      run   : '{Issue t} () -> '{Stream Text} ()
      works : Nat -> Nat
      x     : '{Issue t} () ->{Issue t} ()
  
  Now evaluating any watch expressions (lines starting with
  `>`)... Ctrl+C cancels.

    26 | > Stream.toList <| run do
           ⧩
           ["one", "two", "three", "done"]