amuletml / amulet

An ML-like functional programming language
https://amulet.works/
BSD 3-Clause "New" or "Revised" License
328 stars 16 forks source link

amc: Cannot find CoVar #233

Closed Lupus closed 5 years ago

Lupus commented 5 years ago

I've ran into this error:

amc: Cannot find CoVar {_covarId = 659, _covarName = Just "json", _covarInfo = ValueVar} in escape scope
CallStack (from HasCallStack):
  error, called at src/Backend/Escape.hs:80:25 in amuletml-0.7.0.0-F5LPTJl4HzDD3b5Ruk0Df9:Backend.Escape

Looks like this function is causing it:

  let int = function
  | Int value -> value
  | Float value when has_fractional_part value ->
    Error.throw ("Expected int, got float with fractional part: " ^ string_of_float value)
  (*| Float value -> int_of_float_cast value*)
  | json -> Error.throw ("Expected int, got " ^ show json)

Uncommenting the | Float value -> case makes it compile.

SquidDev commented 5 years ago

Just curious if this is when running with the REPL or using amc compile? If the latter, could you run with --core-lint as well, and provide the output?

Lupus commented 5 years ago

I'm using amc compile. Do you need all of 694KB of output? It starts with:

amc: Core lint failed after `Lowered` with 3 errors
SquidDev commented 5 years ago

Hrmr, we're producing invalid Core, this isn't even a backend bug. That's very worrying.

Either the core output, or your original program if you're happy to share it. I suspect the latter is a little smaller :).

Lupus commented 5 years ago

I was able to trim this down to the following sample:

type a =
  | A1 of a
  | A2 of int

external val make_a : unit -> a = "z"

external val pred : int -> bool = "z"
external val ignore : 'a -> unit = "z"

let some_func = function
| A2 value when pred value -> ()
(* | A2 _ -> Exception.error "" *)
| x -> ignore x

let _ =
  let v = make_a () in
  let _ = some_func v
  ()

Result:

$ amc compile --core-lint test.ml -o /dev/null
amc: Core lint failed after `Lowered` with 3 errors
type a#t1 {
  A1#D2 : a#t1 -> a#t1;
  A2#D3 : int#t-2 -> a#t1
}
make_a#v4 : unit#t-5 -> a#t1 = foreign
pred#v5 : int#t-2 -> bool#t-1 = foreign
ignore#v6 : ∀ (a#'t7 : *). 'a#'t7 -> unit#t-5 = foreign
let some_func#v8 : a#t1 -> unit#t-5 =
  λ (x#v12 : a#t1).
    let ei#v138 : a#t1 -> unit#t-5 =
      λ (ej#v139 : a#t1).
        let ef#v135 : a#t1 -> unit#t-5 =
          ignore#v6:[∀ (a#'t7 : *). 'a#'t7 -> unit#t-5] {a#t1}
        in (* XXX No such variable x#v10 *)
        ef#v135:[a#t1 -> unit#t-5] x#v10:[a#t1]
    in match x#v12:[a#t1] {
      (A2#D3 value#v137:[int#t-2]) [] : a#t1 ->
        let ek#v140 : bool#t-1 =
          let value#v9 : int#t-2 =
            value#v137:[int#t-2]
          in pred#v5:[int#t-2 -> bool#t-1] value#v9:[int#t-2]
        in match ek#v140:[bool#t-1] {
          true [] : bool#t-1 ->
            let value#v9 : int#t-2 =
              value#v137:[int#t-2]
            in unit;
          _ [] : bool#t-1 ->
            (* XXX No such variable x#v10 *)
            ei#v138:[a#t1 -> unit#t-5] x#v10:[a#t1 -> unit#t-5]
        };
      _ [] : a#t1 ->
        (* XXX No such variable x#v10 *)
        ei#v138:[a#t1 -> unit#t-5] x#v10:[a#t1 -> unit#t-5]
    }
let eo#v144 : unit#t-5 =
  let ep#v145 : unit#t-5 =
    let v#v11 : a#t1 =
      make_a#v4:[unit#t-5 -> a#t1] unit
    in let el#v141 : unit#t-5 =
      let em#v142 : unit#t-5 =
        some_func#v8:[a#t1 -> unit#t-5] v#v11:[a#t1]
      in unit
    in unit
  in unit
CallStack (from HasCallStack):
  error, called at src/Core/Lint.hs:99:20 in amuletml-0.7.0.0-F5LPTJl4HzDD3b5Ruk0Df9:Core.Lint
Lupus commented 5 years ago

Ah, forgot to mention that uncommenting this line (* | A2 _ -> Exception.error "" *) makes it compile.

SquidDev commented 5 years ago

Thank you very much for reporting this! Definitely one of the more pesky bugs.

Lupus commented 5 years ago

Cool! Thanks for quick fix :)

Lupus commented 4 years ago

I've stepped in another case, which seems to be root caused by the same bug. Catch-all branch single value pattern caused the compiler to die with same "Cannot find CoVar". Other branches were some nested pattern matches destructuring lists, variants, matching strings.

May be this bug fix deserves a release? Is there somewhat stable snapshot in master somewhere?