unisonweb / unison

A friendly programming language from the future
https://unison-lang.org
Other
5.8k stars 271 forks source link

impossible Lexer Error #5302

Closed ChrisPenner closed 2 months ago

ChrisPenner commented 2 months ago

Pasted something in my editor and ran into this:

  impossible
  CallStack (from HasCallStack):
    error, called at src/Unison/Syntax/Lexer/Unison.hs:206:22 in unison-syntax-0.0.0-HKG1EGnDAh8BtztjOQp4o7:Unison.Syntax.Lexer.Unison

The line number corresponds to this: https://github.com/unisonweb/unison/blob/e9ca76f651d6a21c55244725f2174b30202b8f1c/unison-syntax/src/Unison/Syntax/Lexer/Unison.hs#L206-L208

But weirdly the error message doesn't match 🤔

Here's what was in my scratch file at the time:

    printTime "Decode Nat" 1 (n -> repeat n do decodeNat64be bytes)

suite : '{IO, Exception} ()
suite =
  do
    use List map replicate
    use Nat + - == range
    bytes = 0xsaabbccddeeff1122
    repeat n action =
      if n == 0 then ()
      else
        _ = action()
        repeat (n - 1) action
    printTime "Decode Nat" 1 (n -> repeat n do decodeNat64be bytes)
    printTime
      "Generate 100 random numbers"
      1
      (n -> repeat n do splitmix 0 do replicate 100 do Random.natIn 0 100)
    printTime
      "Count to 1 million" 1 let
        go n = if n == 0 then () else go (n - 1)
        n -> repeat n do go 1000000
    printTime
      "Json parsing (per document)"
      1
      (n -> repeat n do ignore (tryFromText jsonExample))
    printTime "Count to N (per element)" 10000 (n -> repeat n do ())
    printTime "Count to 1000" 10 (n -> repeat n do repeat 1000 do ())
    printTime
      "Mutate a Ref 1000 times" 10 (n ->
        repeat n do
          Scope.run do
            r = Scope.ref 0
            repeat 1000 do Ref.write r (Ref.read r + 1))
    printTime
      "CAS an IO.ref 1000 times" 10 (n ->
        repeat n do
          r = IO.ref 0
          repeat 1000 do
            t = readForCas r
            _ = cas r t (Ticket.read t + 1)
            ())
    printTime "List.range (per element)" 10000 (n -> ignore (range 0 n))
    printTime
      "List.range 0 1000" 10 (n -> ignore (replicate n do range 0 1000))
    printTime
      "Set.fromList (range 0 1000)" 1 let
        ns = range 0 1000
        n -> repeat n do Set.fromList ns
    printTime
      "Map.fromList (range 0 1000)" 1 let
        ns = range 0 1000 |> map (i -> (i, i))
        n -> repeat n do Map.fromList ns
    printTime
      "Map.lookup (1k element map)" 1 let
        ns = range 0 1000 |> map (i -> (i, i)) |> Map.fromList
        n -> repeat n do Map.get 12 ns
    printTime
      "Map.insert (1k element map)" 1 let
        ns = range 0 1000 |> map (i -> (i, i)) |> Map.fromList
        n -> repeat n do Map.insert 10001 0 ns
    printTime
      "List.at (1k element list)" 1 let
        ns = range 0 1000
        n -> repeat n do List.at 500
    printTime
      "Text.split /" 10 let
        uri = "/some/url/path/to/somewhere"
        n -> repeat n do ignore (Text.split ?/ uri)

suite.doc : Doc
suite.doc = {{ Microbenchmark suite. }}

suite.jsonExample : Text
suite.jsonExample =
  "[\n  {\n    \"DisvwrvA\": 5.4467,\n    \"eYuclz4TY7bLRvcxb\": -7.47507849402490527,\n    \"82XrqcLo*7qXR\134F4jAfb\": 366,\n    \"nZD\": 375736097,\n    \"6iDxqktebcE^zpw\": 5,\n    \"uLz&pOyd12\": 582672302889263954,\n    \"hH\": -7545954733892060\n  },\n  \"ft7Z9D`my\",\n  [\n    19175738828846044,\n    7306135675\n  ],\n  \"poT9wL\",\n  \"QDcoszL2\",\n  {\n    \"46b8ksXTSnhT\": -903229659754,\n    \"r2okmplDNj5ir\": -214175168.121479E-6,\n    \"Juj\": 6059153649721736539,\n    \"A\": 1e+9396570477,\n    \"Okxw1B\": 80004564,\n    \"{eRInZv79Acn\": 4\n  },\n  [\n    454.713,\n    5E832157837,\n    -1,\n    9.6E+24067,\n    -603,\n    -3.459575105694,\n    64490047411104497,\n    0.40264464636316176\n  ],\n  {\n    \"GeJ7ghMHnn0u7\": -48496788896E+7554,\n    \"Vci7qg2a\": 969535405035704054,\n    \"6tQezgn6lB4QoER}|es\\\\\": 7.1693271307\n  }\n]"

time : Nat -> (Nat ->{g} ()) ->{g, IO, Exception} Duration
time n action =
  trial tries samples k =
    use Clock monotonic
    use Duration -
    use List :+
    use Nat + >
    t0 = monotonic()
    action k
    action k
    action k
    action k
    action k
    t1 = monotonic()
    overall = t1 - t0 Duration./ +5
    S = 3
    F = 4
    if overall Duration.< milliseconds +200 then
      trial tries samples (k Nat.* F)
    else
      if List.size samples Nat.< S then trial tries (samples :+ overall) k
      else
        exceedsBounds = Each.count do
          use Duration * / <
          a = each samples
          b = each samples
          guard (+5 * a / +4 < b)
        if (exceedsBounds > 0) && (tries Nat.< 4) then
          use Nat * /
          k' = k * 5 / 4
          trial (tries + 1) [] k'
        else
          d = List.sort samples |> List.unsafeAt (S Nat./ 2)
          d Duration./ Nat.toInt k
  trial 0 [] n

time.doc : Doc
time.doc =
  {{
  `` time n action `` returns the {type Duration} taken by `action` per trial.

  `n` is increased until the sample time is at least 200 milliseconds and
  sample variance is low.
  }}
ceedubs commented 2 months ago

This was just addressed in https://github.com/unisonweb/unison/pull/5297 . I'm guessing you don't have that change yet and that is why the error message is different?

ChrisPenner commented 2 months ago

Oh great! Yeah I'm probably just a bit behind; thanks!

sellout commented 1 month ago

Oh, this is good though – I had just changed the error handling because I didn’t have a transcript to reproduce this with (and it clearly wasn’t impossible to hit). So this will help fix #5179.