From 15a4ac210f1d69e52557ada6fc54f7f995853bf4 Mon Sep 17 00:00:00 2001 From: Claudio Russo Date: Fri, 4 Oct 2024 13:51:22 +0100 Subject: [PATCH] feat: suggest corrections for unbound identifiers/fields based on distance metric (#4720) Add flag --ai-errors to tailor error reporting for human (default) or artificial users. For humans, instead of reporting that a value or type identifier is not available in references or projections, we now suggest likely candidates based on: * whether the identifier is a prefix of the candidate identifiers. * whether the identifier is some [edit distance](https://en.wikipedia.org/wiki/Levenshtein_distance) away from the candidate identifiers. and report identifiers in order of edit distance. When the object/actor/module projected from has few bindings (<16), we display them with their types, to avoid producing huge error messages. With --ai-errors, we don't give hints but display all available bindings with their types (Thanks to Claude.ai for coughing up an implementation.) --- Changelog.md | 8 +- doc/md/reference/compiler-ref.md | 5 +- src/exes/moc.ml | 1 + src/lib/lib.ml | 34 +++ src/lib/lib.mli | 1 + src/mo_config/flags.ml | 1 + src/mo_frontend/typing.ml | 122 ++++++++- src/mo_types/type.ml | 2 +- src/prelude/internals.mo | 24 +- test/fail/ok/M0028.tc.ok | 2 +- test/fail/ok/bad-type-comp.tc.ok | 2 + test/fail/ok/modexp1.tc.ok | 2 +- test/fail/ok/pretty.tc.ok | 2 +- test/fail/ok/suggest-label-ai.tc.ok | 3 + test/fail/ok/suggest-label-ai.tc.ret.ok | 1 + test/fail/ok/suggest-label.tc.ok | 2 + test/fail/ok/suggest-label.tc.ret.ok | 1 + test/fail/ok/suggest-local-ai.tc.ok | 3 + test/fail/ok/suggest-local-ai.tc.ret.ok | 1 + test/fail/ok/suggest-local-type-ai.tc.ok | 3 + test/fail/ok/suggest-local-type-ai.tc.ret.ok | 1 + test/fail/ok/suggest-local-type.tc.ok | 2 + test/fail/ok/suggest-local-type.tc.ret.ok | 1 + test/fail/ok/suggest-local.tc.ok | 2 + test/fail/ok/suggest-local.tc.ret.ok | 1 + test/fail/ok/suggest-long-ai.tc.ok | 259 +++++++++++++++++++ test/fail/ok/suggest-long-ai.tc.ret.ok | 1 + test/fail/ok/suggest-long.tc.ok | 2 + test/fail/ok/suggest-long.tc.ret.ok | 1 + test/fail/ok/suggest-short-ai.tc.ok | 259 +++++++++++++++++++ test/fail/ok/suggest-short-ai.tc.ret.ok | 1 + test/fail/ok/suggest-short.tc.ok | 2 + test/fail/ok/suggest-short.tc.ret.ok | 1 + test/fail/ok/suggest-type-ai.tc.ok | 25 ++ test/fail/ok/suggest-type-ai.tc.ret.ok | 1 + test/fail/ok/suggest-type.tc.ok | 24 ++ test/fail/ok/suggest-type.tc.ret.ok | 1 + test/fail/suggest-label-ai.mo | 4 + test/fail/suggest-label.mo | 3 + test/fail/suggest-local-ai.mo | 3 + test/fail/suggest-local-type-ai.mo | 3 + test/fail/suggest-local-type.mo | 2 + test/fail/suggest-local.mo | 2 + test/fail/suggest-long-ai.mo | 4 + test/fail/suggest-long.mo | 3 + test/fail/suggest-short-ai.mo | 4 + test/fail/suggest-short.mo | 3 + test/fail/suggest-type-ai.mo | 4 + test/fail/suggest-type.mo | 3 + 49 files changed, 811 insertions(+), 31 deletions(-) create mode 100644 test/fail/ok/suggest-label-ai.tc.ok create mode 100644 test/fail/ok/suggest-label-ai.tc.ret.ok create mode 100644 test/fail/ok/suggest-label.tc.ok create mode 100644 test/fail/ok/suggest-label.tc.ret.ok create mode 100644 test/fail/ok/suggest-local-ai.tc.ok create mode 100644 test/fail/ok/suggest-local-ai.tc.ret.ok create mode 100644 test/fail/ok/suggest-local-type-ai.tc.ok create mode 100644 test/fail/ok/suggest-local-type-ai.tc.ret.ok create mode 100644 test/fail/ok/suggest-local-type.tc.ok create mode 100644 test/fail/ok/suggest-local-type.tc.ret.ok create mode 100644 test/fail/ok/suggest-local.tc.ok create mode 100644 test/fail/ok/suggest-local.tc.ret.ok create mode 100644 test/fail/ok/suggest-long-ai.tc.ok create mode 100644 test/fail/ok/suggest-long-ai.tc.ret.ok create mode 100644 test/fail/ok/suggest-long.tc.ok create mode 100644 test/fail/ok/suggest-long.tc.ret.ok create mode 100644 test/fail/ok/suggest-short-ai.tc.ok create mode 100644 test/fail/ok/suggest-short-ai.tc.ret.ok create mode 100644 test/fail/ok/suggest-short.tc.ok create mode 100644 test/fail/ok/suggest-short.tc.ret.ok create mode 100644 test/fail/ok/suggest-type-ai.tc.ok create mode 100644 test/fail/ok/suggest-type-ai.tc.ret.ok create mode 100644 test/fail/ok/suggest-type.tc.ok create mode 100644 test/fail/ok/suggest-type.tc.ret.ok create mode 100644 test/fail/suggest-label-ai.mo create mode 100644 test/fail/suggest-label.mo create mode 100644 test/fail/suggest-local-ai.mo create mode 100644 test/fail/suggest-local-type-ai.mo create mode 100644 test/fail/suggest-local-type.mo create mode 100644 test/fail/suggest-local.mo create mode 100644 test/fail/suggest-long-ai.mo create mode 100644 test/fail/suggest-long.mo create mode 100644 test/fail/suggest-short-ai.mo create mode 100644 test/fail/suggest-short.mo create mode 100644 test/fail/suggest-type-ai.mo create mode 100644 test/fail/suggest-type.mo diff --git a/Changelog.md b/Changelog.md index 0782e1ac7ff..bab1bb0b4b6 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,11 @@ # Motoko compiler changelog +* motoko (`moc`) + + * Improved error messages for unbound identifiers and fields that avoid reporting large types and use an edit-distance based metric to suggest alternatives (#4720). + + * Flag `--ai-errors` to tailor error messages to AI clients (#4720). + ## 0.13.0 (2024-09-17) * motoko (`moc`) @@ -13,7 +19,7 @@ * The Wasm main memory (heap) is retained on upgrade with new program versions directly picking up this state. * The Wasm main memory has been extended to 64-bit to scale as large as stable memory in the future. * The runtime system checks that data changes of new program versions are compatible with the old state. - + Implications: * Upgrades become extremely fast, only depending on the number of types, not on the number of heap objects. * Upgrades will no longer hit the IC instruction limit, even for maximum heap usage. diff --git a/doc/md/reference/compiler-ref.md b/doc/md/reference/compiler-ref.md index b921353d9b8..926cacde603 100644 --- a/doc/md/reference/compiler-ref.md +++ b/doc/md/reference/compiler-ref.md @@ -26,6 +26,7 @@ You can use the following options with the `moc` command. | Option | Description | |-------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------| +| `--ai-errors` | Emit AI tailored error messages. | | `--actor-idl ` | Specifies a path to actor IDL (Candid) files. | | `--actor-alias ` | Specifies an actor import alias. | | `--args ` | Read additional newline separated command line arguments from ``. | @@ -39,12 +40,12 @@ You can use the following options with the `moc` command. | `--error-detail ` | Set level of error message detail for syntax errors, n in \[0..3\] (default 2). | | `--experimental-stable-memory ` | Select support for the deprecated `ExperimentalStableMemory.mo` library (n < 0: error, n = 0: warn, n > 0: allow) (default 0). | | `-fno-shared-code` | Do not share low-level utility code: larger code size but decreased cycle consumption (default). | -| `--generational-gc` | Use generational GC (not supported with enhanced orthogonal persistence). | +| `--generational-gc` | Use generational GC (not supported with enhanced orthogonal persistence). | | `-fshared-code` | Do share low-level utility code: smaller code size but increased cycle consumption. | | `-help`,`--help` | Displays usage information. | | `--hide-warnings` | Hides compiler warnings. | | `-Werror` | Treat warnings as errors. | -| `--incremental-gc` | Use incremental GC (default of enhanced orthogonal persistence, also available for classical persistence). | +| `--incremental-gc` | Use incremental GC (default of enhanced orthogonal persistence, also available for classical persistence). | | `--idl` | Compile binary and emit Candid IDL specification to `.did` file. | | `-i` | Runs the compiler in an interactive read–eval–print loop (REPL) shell so you can evaluate program execution (implies -r). | | `--map` | Outputs a JavaScript source map. | diff --git a/src/exes/moc.ml b/src/exes/moc.ml index 9b81a6fcb4b..648efb9f8dd 100644 --- a/src/exes/moc.ml +++ b/src/exes/moc.ml @@ -37,6 +37,7 @@ let valid_metadata_names = "motoko:compiler"] let argspec = [ + "--ai-errors", Arg.Set Flags.ai_errors, " emit AI tailored errors"; "-c", Arg.Unit (set_mode Compile), " compile programs to WebAssembly"; "-g", Arg.Set Flags.debug_info, " generate source-level debug information"; "-r", Arg.Unit (set_mode Run), " interpret programs"; diff --git a/src/lib/lib.ml b/src/lib/lib.ml index 6b0cd938ad9..a16a038179f 100644 --- a/src/lib/lib.ml +++ b/src/lib/lib.ml @@ -236,6 +236,40 @@ struct | c -> Buffer.add_char buf c done; Buffer.contents buf + + (* Courtesy of Claude.ai *) + let levenshtein_distance s t = + let m = String.length s + and n = String.length t in + + (* Ensure s is the shorter string for optimization *) + let (s, t, m, n) = if m > n then (t, s, n, m) else (s, t, m, n) in + + (* Initialize the previous row *) + let previous_row = Array.init (m + 1) (fun i -> i) in + + (* Compute the distance *) + for i = 1 to n do + let current_row = Array.make (m + 1) 0 in + current_row.(0) <- i; + + for j = 1 to m do + let cost = if s.[j-1] = t.[i-1] then 0 else 1 in + current_row.(j) <- min + (min + (previous_row.(j) + 1) (* Deletion *) + (current_row.(j-1) + 1) (* Insertion *) + ) + (previous_row.(j-1) + cost) (* Substitution *) + done; + + (* Swap rows *) + Array.blit current_row 0 previous_row 0 (m + 1) + done; + + (* Return the distance *) + previous_row.(m) + end module Utf8 = diff --git a/src/lib/lib.mli b/src/lib/lib.mli index 795e35f1054..cd748881a39 100644 --- a/src/lib/lib.mli +++ b/src/lib/lib.mli @@ -160,6 +160,7 @@ sig val chop_prefix : string -> string -> string option val chop_suffix : string -> string -> string option val lightweight_escaped : string -> string + val levenshtein_distance : string -> string -> int end module CRC : diff --git a/src/mo_config/flags.ml b/src/mo_config/flags.ml index 2b92d84b80e..d514afcf6cc 100644 --- a/src/mo_config/flags.ml +++ b/src/mo_config/flags.ml @@ -11,6 +11,7 @@ type instruction_limits = { update_call: int; } +let ai_errors = ref false let trace = ref false let verbose = ref false let print_warnings = ref true diff --git a/src/mo_frontend/typing.ml b/src/mo_frontend/typing.ml index 18be0d87362..f3aedaa4943 100644 --- a/src/mo_frontend/typing.ml +++ b/src/mo_frontend/typing.ml @@ -114,6 +114,32 @@ let kind_of_field_pattern pf = match pf.it with | { id; pat = { it = VarP pat_id; _ } } when id = pat_id -> Scope.FieldReference | _ -> Scope.Declaration +(* Suggestions *) + +let suggest desc id ids = + if !Flags.ai_errors then + Printf.sprintf + "\nThe %s %s is not available. Try something else?" + desc + id + else + let suggestions = + let limit = Lib.Int.log2 (String.length id) in + let distance = Lib.String.levenshtein_distance id in + let weighted_ids = List.filter_map (fun id0 -> + let d = distance id0 in + if Lib.String.starts_with id id0 || d <= limit then + Some (d, id0) + else None) ids in + List.sort compare weighted_ids |> List.map snd + in + if suggestions = [] then "" + else + let rest, last = Lib.List.split_last suggestions in + Printf.sprintf "\nDid you mean %s %s?" + desc + ((if rest <> [] then (String.concat ", " rest) ^ " or " else "") ^ last) + (* Error bookkeeping *) exception Recover @@ -128,6 +154,54 @@ let display_typ = Lib.Format.display T.pp_typ let display_typ_expand = Lib.Format.display T.pp_typ_expand +let display_obj fmt (s, fs) = + if !Flags.ai_errors || (List.length fs) < 16 then + Format.fprintf fmt "type:%a" display_typ (T.Obj(s, fs)) + else + Format.fprintf fmt "%s." (String.trim(T.string_of_obj_sort s)) + +let display_vals fmt vals = + if !Flags.ai_errors then + let tfs = T.Env.fold (fun x (t, _, _, _) acc -> + if x = "Prim" || (String.length x >= 0 && x.[0] = '@') + then acc + else T.{lab = x; src = {depr = None; region = Source.no_region }; typ = t}::acc) + vals [] + in + let ty = T.Obj(T.Object, List.rev tfs) in + Format.fprintf fmt " in environment:%a" display_typ ty + else + Format.fprintf fmt "" + +let display_labs fmt labs = + if !Flags.ai_errors then + let tfs = T.Env.fold (fun x t acc -> + T.{lab = x; src = {depr = None; region = Source.no_region }; typ = t}::acc) + labs [] + in + let ty = T.Obj(T.Object, List.rev tfs) in + Format.fprintf fmt " in label environment:%a" display_typ ty + else + Format.fprintf fmt "" + +let display_typs fmt typs = + if !Flags.ai_errors then + let tfs = T.Env.fold (fun x c acc -> + if (String.length x >= 0 && (x.[0] = '@' || x.[0] = '$')) || + T.(match Cons.kind c with + | Def ([], Prim _) + | Def ([], Any) + | Def ([], Non) -> string_of_con c = x + | _ -> false) + then acc + else T.{lab = x; src = {depr = None; region = Source.no_region }; typ = T.Typ c}::acc) + typs [] + in + let ty = T.Obj(T.Object, List.rev tfs) in + Format.fprintf fmt " in type environment:%a" display_typ ty + else + Format.fprintf fmt "" + let type_error at code text : Diag.message = Diag.error_message at code "type" text @@ -398,8 +472,11 @@ and check_obj_path' env path : T.typ = error env id.at "M0024" "cannot infer type of forward variable reference %s" id.it | Some (t, _, _, Available) -> t | Some (t, _, _, Unavailable) -> - error env id.at "M0025" "unavailable variable %s" id.it - | None -> error env id.at "M0026" "unbound variable %s" id.it + error env id.at "M0025" "unavailable variable %s" id.it + | None -> + error env id.at "M0026" "unbound variable %s%a%s" id.it + display_vals env.vals + (suggest "variable" id.it (T.Env.keys env.vals)) ) | DotH (path', id) -> let s, fs = check_obj_path env path' in @@ -408,8 +485,14 @@ and check_obj_path' env path : T.typ = error env id.at "M0027" "cannot infer type of forward field reference %s" id.it | t -> t | exception Invalid_argument _ -> - error env id.at "M0028" "field %s does not exist in type%a" - id.it display_typ_expand (T.Obj (s, fs)) + error env id.at "M0028" "field %s does not exist in %a%s" + id.it + display_obj (s, fs) + (suggest "field" id.it + (List.filter_map + (function + {T.typ=T.Typ _;_} -> None + | {T.lab;_} -> Some lab) fs)) let rec check_typ_path env path : T.con = let c = check_typ_path' env path in @@ -422,7 +505,10 @@ and check_typ_path' env path : T.con = use_identifier env id.it; (match T.Env.find_opt id.it env.typs with | Some c -> c - | None -> error env id.at "M0029" "unbound type %s" id.it + | None -> + error env id.at "M0029" "unbound type %s%a%s" id.it + display_typs env.typs + (suggest "type" id.it (T.Env.keys env.typs)) ) | DotH (path', id) -> let s, fs = check_obj_path env path' in @@ -431,9 +517,12 @@ and check_typ_path' env path : T.con = check_deprecation env path.at "type field" id.it (T.lookup_typ_deprecation id.it fs); c | exception Invalid_argument _ -> - error env id.at "M0030" "type field %s does not exist in type%a" + error env id.at "M0030" "type field %s does not exist in type%a%s" id.it display_typ_expand (T.Obj (s, fs)) - + (suggest "type field" id.it + (List.filter_map + (function { T.lab; T.typ=T.Typ _;_ } -> Some lab + | _ -> None) fs)) (* Type helpers *) @@ -1160,7 +1249,9 @@ and infer_exp'' env exp : T.typ = else t | Some (t, _, _, Available) -> id.note <- (if T.is_mut t then Var else Const); t | None -> - error env id.at "M0057" "unbound variable %s" id.it + error env id.at "M0057" "unbound variable %s%a%s" id.it + display_vals env.vals + (suggest "variable" id.it (T.Env.keys env.vals)) ) | LitE lit -> T.Prim (infer_lit env lit exp.at) @@ -1376,7 +1467,7 @@ and infer_exp'' env exp : T.typ = T.(glb t_base (Obj (Object, sort T.compare_field fts))) | DotE (exp1, id) -> let t1 = infer_exp_promote env exp1 in - let _s, tfs = + let s, tfs = try T.as_obj_sub [id.it] t1 with Invalid_argument _ -> try array_obj (T.as_array_sub t1) with Invalid_argument _ -> try blob_obj (T.as_prim_sub T.Blob t1) with Invalid_argument _ -> @@ -1396,9 +1487,14 @@ and infer_exp'' env exp : T.typ = t | exception Invalid_argument _ -> error env exp1.at "M0072" - "field %s does not exist in type%a" + "field %s does not exist in %a%s" id.it - display_typ_expand t1 + display_obj (s, tfs) + (suggest "field" id.it + (List.filter_map + (function + { T.typ=T.Typ _;_} -> None + | {T.lab;_} -> Some lab) tfs)) ) | AssignE (exp1, exp2) -> if not env.pre then begin @@ -1596,7 +1692,9 @@ and infer_exp'' env exp : T.typ = match String.split_on_char ' ' id.it with | ["continue"; name] -> name | _ -> id.it - in local_error env id.at "M0083" "unbound label %s" name + in local_error env id.at "M0083" "unbound label %s%a%s" name + display_labs env.labs + (suggest "label" id.it (T.Env.keys env.labs)) ); T.Non | RetE exp1 -> diff --git a/src/mo_types/type.ml b/src/mo_types/type.ml index 828cc7e38c3..bc8aeb5b451 100644 --- a/src/mo_types/type.ml +++ b/src/mo_types/type.ml @@ -1379,7 +1379,7 @@ let motoko_runtime_information_type = let motoko_runtime_information_fld = { lab = "__motoko_runtime_information"; - typ = Func(Shared Query, Promises, [scope_bind], [], + typ = Func(Shared Query, Promises, [scope_bind], [], [ motoko_runtime_information_type ]); src = empty_src; } diff --git a/src/prelude/internals.mo b/src/prelude/internals.mo index d5aff87983d..b98be29c768 100644 --- a/src/prelude/internals.mo +++ b/src/prelude/internals.mo @@ -400,13 +400,13 @@ module @ManagementCanister = { }; }; -type WasmMemoryPersistence = { +type @WasmMemoryPersistence = { #Keep; #Replace; }; -type UpgradeOptions = { - wasm_memory_persistence: ?WasmMemoryPersistence; +type @UpgradeOptions = { + wasm_memory_persistence: ?@WasmMemoryPersistence; }; let @ic00 = actor "aaaaa-aa" : @@ -416,10 +416,10 @@ let @ic00 = actor "aaaaa-aa" : sender_canister_version : ?Nat64 } -> async { canister_id : Principal }; install_code : { - mode : { - #install; - #reinstall; - #upgrade : ?UpgradeOptions; + mode : { + #install; + #reinstall; + #upgrade : ?@UpgradeOptions; }; canister_id : Principal; wasm_module : @ManagementCanister.wasm_module; @@ -434,7 +434,7 @@ func @install_actor_helper( #install : Principal; #reinstall : actor {} ; #upgrade : actor {} ; - #upgrade_with_persistence : { wasm_memory_persistence: WasmMemoryPersistence; canister: actor {} }; + #upgrade_with_persistence : { wasm_memory_persistence: @WasmMemoryPersistence; canister: actor {} }; }, enhanced_orthogonal_persistence : Bool, wasm_module : Blob, @@ -459,10 +459,10 @@ func @install_actor_helper( (#reinstall, (prim "principalOfActor" : (actor {}) -> Principal) actor1) }; case (#upgrade actor2) { - let wasm_memory_persistence = if enhanced_orthogonal_persistence { - ?(#Keep) - } else { - null + let wasm_memory_persistence = if enhanced_orthogonal_persistence { + ?(#Keep) + } else { + null }; let upgradeOptions = { wasm_memory_persistence; diff --git a/test/fail/ok/M0028.tc.ok b/test/fail/ok/M0028.tc.ok index f3d3ad55e7e..c14eef5e016 100644 --- a/test/fail/ok/M0028.tc.ok +++ b/test/fail/ok/M0028.tc.ok @@ -1,2 +1,2 @@ -M0028.mo:2.11-2.12: type error [M0028], field Y does not exist in type +M0028.mo:2.11-2.12: type error [M0028], field Y does not exist in type: module {} diff --git a/test/fail/ok/bad-type-comp.tc.ok b/test/fail/ok/bad-type-comp.tc.ok index d5100dde5e5..8335791eda3 100644 --- a/test/fail/ok/bad-type-comp.tc.ok +++ b/test/fail/ok/bad-type-comp.tc.ok @@ -8,7 +8,9 @@ cannot produce expected type module {type T = Null} bad-type-comp.mo:7.73-7.74: type error [M0018], duplicate type field name T in object type bad-type-comp.mo:11.15-11.16: type error [M0029], unbound type T +Did you mean type Text? bad-type-comp.mo:17.15-17.16: type error [M0029], unbound type U bad-type-comp.mo:24.17-24.27: type error [M0137], type T = A__9 references type parameter A__9 from an outer scope bad-type-comp.mo:29.23-29.33: type error [M0137], type T = A__10 references type parameter A__10 from an outer scope bad-type-comp.mo:35.25-35.26: type error [M0029], unbound type T +Did you mean type Text? diff --git a/test/fail/ok/modexp1.tc.ok b/test/fail/ok/modexp1.tc.ok index 226cc7a9d71..19059dae89e 100644 --- a/test/fail/ok/modexp1.tc.ok +++ b/test/fail/ok/modexp1.tc.ok @@ -1,2 +1,2 @@ -modexp1.mo:8.13-8.14: type error [M0072], field g does not exist in type +modexp1.mo:8.13-8.14: type error [M0072], field g does not exist in type: module {f : () -> ()} diff --git a/test/fail/ok/pretty.tc.ok b/test/fail/ok/pretty.tc.ok index d17d5ce522e..0f5a045f01a 100644 --- a/test/fail/ok/pretty.tc.ok +++ b/test/fail/ok/pretty.tc.ok @@ -45,7 +45,7 @@ pretty.mo:28.23-28.24: type error [M0096], expression of type } cannot produce expected type Nat -pretty.mo:40.1-40.12: type error [M0072], field foo does not exist in type +pretty.mo:40.1-40.12: type error [M0072], field foo does not exist in type: module { bar1 : Nat; bar2 : Nat; diff --git a/test/fail/ok/suggest-label-ai.tc.ok b/test/fail/ok/suggest-label-ai.tc.ok new file mode 100644 index 00000000000..49c9e4e4aca --- /dev/null +++ b/test/fail/ok/suggest-label-ai.tc.ok @@ -0,0 +1,3 @@ +suggest-label-ai.mo:3.9-3.11: type error [M0083], unbound label fo in label environment: + {foo : ()} +The label fo is not available. Try something else? diff --git a/test/fail/ok/suggest-label-ai.tc.ret.ok b/test/fail/ok/suggest-label-ai.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-label-ai.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-label.tc.ok b/test/fail/ok/suggest-label.tc.ok new file mode 100644 index 00000000000..f514bf245e5 --- /dev/null +++ b/test/fail/ok/suggest-label.tc.ok @@ -0,0 +1,2 @@ +suggest-label.mo:2.9-2.11: type error [M0083], unbound label fo +Did you mean label foo? diff --git a/test/fail/ok/suggest-label.tc.ret.ok b/test/fail/ok/suggest-label.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-label.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-local-ai.tc.ok b/test/fail/ok/suggest-local-ai.tc.ok new file mode 100644 index 00000000000..3ea48f96666 --- /dev/null +++ b/test/fail/ok/suggest-local-ai.tc.ok @@ -0,0 +1,3 @@ +suggest-local-ai.mo:3.1-3.2: type error [M0057], unbound variable x in environment: + {xxx : Nat} +The variable x is not available. Try something else? diff --git a/test/fail/ok/suggest-local-ai.tc.ret.ok b/test/fail/ok/suggest-local-ai.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-local-ai.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-local-type-ai.tc.ok b/test/fail/ok/suggest-local-type-ai.tc.ok new file mode 100644 index 00000000000..90e44da1d98 --- /dev/null +++ b/test/fail/ok/suggest-local-type-ai.tc.ok @@ -0,0 +1,3 @@ +suggest-local-type-ai.mo:3.13-3.15: type error [M0029], unbound type Fo in type environment: + {type Foo = Int; type Zap <: ???} +The type Fo is not available. Try something else? diff --git a/test/fail/ok/suggest-local-type-ai.tc.ret.ok b/test/fail/ok/suggest-local-type-ai.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-local-type-ai.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-local-type.tc.ok b/test/fail/ok/suggest-local-type.tc.ok new file mode 100644 index 00000000000..1dea0ca8b86 --- /dev/null +++ b/test/fail/ok/suggest-local-type.tc.ok @@ -0,0 +1,2 @@ +suggest-local-type.mo:2.13-2.15: type error [M0029], unbound type Fo +Did you mean type Foo? diff --git a/test/fail/ok/suggest-local-type.tc.ret.ok b/test/fail/ok/suggest-local-type.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-local-type.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-local.tc.ok b/test/fail/ok/suggest-local.tc.ok new file mode 100644 index 00000000000..9ddc338e23f --- /dev/null +++ b/test/fail/ok/suggest-local.tc.ok @@ -0,0 +1,2 @@ +suggest-local.mo:2.1-2.2: type error [M0057], unbound variable x +Did you mean variable xxx? diff --git a/test/fail/ok/suggest-local.tc.ret.ok b/test/fail/ok/suggest-local.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-local.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-long-ai.tc.ok b/test/fail/ok/suggest-long-ai.tc.ok new file mode 100644 index 00000000000..7f50d74de08 --- /dev/null +++ b/test/fail/ok/suggest-long-ai.tc.ok @@ -0,0 +1,259 @@ +suggest-long-ai.mo:4.1-4.5: type error [M0072], field stableM does not exist in type: + module { + type ErrorCode = + { + #call_error : {err_code : Nat32}; + #canister_error; + #canister_reject; + #destination_invalid; + #future : Nat32; + #system_fatal; + #system_transient + }; + Array_init : (Nat, T) -> [var T]; + Array_tabulate : (Nat, Nat -> T) -> [T]; + Ret : () -> T; + Types : + module { + type Any = Any; + type Blob = Blob; + type Bool = Bool; + type Char = Char; + type Error = Error; + type Float = Float; + type Int = Int; + type Int16 = Int16; + type Int32 = Int32; + type Int64 = Int64; + type Int8 = Int8; + type Nat = Nat; + type Nat16 = Nat16; + type Nat32 = Nat32; + type Nat64 = Nat64; + type Nat8 = Nat8; + type None = None; + type Null = Null; + type Principal = Principal; + type Region = Region; + type Text = Text + }; + abs : Int -> Nat; + arccos : Float -> Float; + arcsin : Float -> Float; + arctan : Float -> Float; + arctan2 : (Float, Float) -> Float; + arrayMutToBlob : [var Nat8] -> Blob; + arrayToBlob : [Nat8] -> Blob; + blobCompare : (Blob, Blob) -> Int8; + blobOfPrincipal : Principal -> Blob; + blobToArray : Blob -> [Nat8]; + blobToArrayMut : Blob -> [var Nat8]; + btstInt16 : (Int16, Int16) -> Bool; + btstInt32 : (Int32, Int32) -> Bool; + btstInt64 : (Int64, Int64) -> Bool; + btstInt8 : (Int8, Int8) -> Bool; + btstNat16 : (Nat16, Nat16) -> Bool; + btstNat32 : (Nat32, Nat32) -> Bool; + btstNat64 : (Nat64, Nat64) -> Bool; + btstNat8 : (Nat8, Nat8) -> Bool; + call_raw : (Principal, Text, Blob) -> async Blob; + cancelTimer : Nat -> (); + canisterVersion : () -> Nat64; + charIsAlphabetic : Char -> Bool; + charIsLowercase : Char -> Bool; + charIsUppercase : Char -> Bool; + charIsWhitespace : Char -> Bool; + charToLower : Char -> Char; + charToNat32 : Char -> Nat32; + charToText : Char -> Text; + charToUpper : Char -> Char; + clzInt16 : Int16 -> Int16; + clzInt32 : Int32 -> Int32; + clzInt64 : Int64 -> Int64; + clzInt8 : Int8 -> Int8; + clzNat16 : Nat16 -> Nat16; + clzNat32 : Nat32 -> Nat32; + clzNat64 : Nat64 -> Nat64; + clzNat8 : Nat8 -> Nat8; + cos : Float -> Float; + createActor : (Blob, Blob) -> async Principal; + ctzInt16 : Int16 -> Int16; + ctzInt32 : Int32 -> Int32; + ctzInt64 : Int64 -> Int64; + ctzInt8 : Int8 -> Int8; + ctzNat16 : Nat16 -> Nat16; + ctzNat32 : Nat32 -> Nat32; + ctzNat64 : Nat64 -> Nat64; + ctzNat8 : Nat8 -> Nat8; + cyclesAccept : Nat -> Nat; + cyclesAdd : Nat -> (); + cyclesAvailable : () -> Nat; + cyclesBalance : () -> Nat; + cyclesBurn : Nat -> Nat; + cyclesRefunded : () -> Nat; + debugPrint : Text -> (); + debugPrintChar : Char -> (); + debugPrintInt : Int -> (); + debugPrintNat : Nat -> (); + decodeUtf8 : Blob -> ?Text; + encodeUtf8 : Text -> Blob; + error : Text -> Error; + errorCode : Error -> ErrorCode; + errorMessage : Error -> Text; + exists : (T -> Bool) -> Bool; + exp : Float -> Float; + floatAbs : Float -> Float; + floatCeil : Float -> Float; + floatCopySign : (Float, Float) -> Float; + floatFloor : Float -> Float; + floatMax : (Float, Float) -> Float; + floatMin : (Float, Float) -> Float; + floatNearest : Float -> Float; + floatSqrt : Float -> Float; + floatToFormattedText : (Float, Nat8, Nat8) -> Text; + floatToInt : Float -> Int; + floatToInt64 : Float -> Int64; + floatToText : Float -> Text; + floatTrunc : Float -> Float; + forall : (T -> Bool) -> Bool; + getCandidLimits : + () -> {bias : Nat32; denominator : Nat32; numerator : Nat32}; + getCertificate : () -> ?Blob; + hashBlob : Blob -> Nat32; + idlHash : Text -> Nat32; + int16ToInt : Int16 -> Int; + int16ToInt32 : Int16 -> Int32; + int16ToInt8 : Int16 -> Int8; + int16ToNat16 : Int16 -> Nat16; + int32ToInt : Int32 -> Int; + int32ToInt16 : Int32 -> Int16; + int32ToInt64 : Int32 -> Int64; + int32ToNat32 : Int32 -> Nat32; + int64ToFloat : Int64 -> Float; + int64ToInt : Int64 -> Int; + int64ToInt32 : Int64 -> Int32; + int64ToNat64 : Int64 -> Nat64; + int8ToInt : Int8 -> Int; + int8ToInt16 : Int8 -> Int16; + int8ToNat8 : Int8 -> Nat8; + intToFloat : Int -> Float; + intToInt16 : Int -> Int16; + intToInt16Wrap : Int -> Int16; + intToInt32 : Int -> Int32; + intToInt32Wrap : Int -> Int32; + intToInt64 : Int -> Int64; + intToInt64Wrap : Int -> Int64; + intToInt8 : Int -> Int8; + intToInt8Wrap : Int -> Int8; + intToNat16Wrap : Int -> Nat16; + intToNat32Wrap : Int -> Nat32; + intToNat64Wrap : Int -> Nat64; + intToNat8Wrap : Int -> Nat8; + isController : Principal -> Bool; + log : Float -> Float; + nat16ToInt16 : Nat16 -> Int16; + nat16ToNat : Nat16 -> Nat; + nat16ToNat32 : Nat16 -> Nat32; + nat16ToNat8 : Nat16 -> Nat8; + nat32ToChar : Nat32 -> Char; + nat32ToInt32 : Nat32 -> Int32; + nat32ToNat : Nat32 -> Nat; + nat32ToNat16 : Nat32 -> Nat16; + nat32ToNat64 : Nat32 -> Nat64; + nat64ToInt64 : Nat64 -> Int64; + nat64ToNat : Nat64 -> Nat; + nat64ToNat32 : Nat64 -> Nat32; + nat8ToInt8 : Nat8 -> Int8; + nat8ToNat : Nat8 -> Nat; + nat8ToNat16 : Nat8 -> Nat16; + natToNat16 : Nat -> Nat16; + natToNat32 : Nat -> Nat32; + natToNat64 : Nat -> Nat64; + natToNat8 : Nat -> Nat8; + performanceCounter : Nat32 -> Nat64; + popcntInt16 : Int16 -> Int16; + popcntInt32 : Int32 -> Int32; + popcntInt64 : Int64 -> Int64; + popcntInt8 : Int8 -> Int8; + popcntNat16 : Nat16 -> Nat16; + popcntNat32 : Nat32 -> Nat32; + popcntNat64 : Nat64 -> Nat64; + popcntNat8 : Nat8 -> Nat8; + principalOfActor : (actor {}) -> Principal; + principalOfBlob : Blob -> Principal; + regionGrow : (Region, Nat64) -> Nat64; + regionId : Region -> Nat; + regionLoadBlob : (Region, Nat64, Nat) -> Blob; + regionLoadFloat : (Region, Nat64) -> Float; + regionLoadInt16 : (Region, Nat64) -> Int16; + regionLoadInt32 : (Region, Nat64) -> Int32; + regionLoadInt64 : (Region, Nat64) -> Int64; + regionLoadInt8 : (Region, Nat64) -> Int8; + regionLoadNat16 : (Region, Nat64) -> Nat16; + regionLoadNat32 : (Region, Nat64) -> Nat32; + regionLoadNat64 : (Region, Nat64) -> Nat64; + regionLoadNat8 : (Region, Nat64) -> Nat8; + regionNew : () -> Region; + regionSize : Region -> Nat64; + regionStoreBlob : (Region, Nat64, Blob) -> (); + regionStoreFloat : (Region, Nat64, Float) -> (); + regionStoreInt16 : (Region, Nat64, Int16) -> (); + regionStoreInt32 : (Region, Nat64, Int32) -> (); + regionStoreInt64 : (Region, Nat64, Int64) -> (); + regionStoreInt8 : (Region, Nat64, Int8) -> (); + regionStoreNat16 : (Region, Nat64, Nat16) -> (); + regionStoreNat32 : (Region, Nat64, Nat32) -> (); + regionStoreNat64 : (Region, Nat64, Nat64) -> (); + regionStoreNat8 : (Region, Nat64, Nat8) -> (); + rts_callback_table_count : () -> Nat; + rts_callback_table_size : () -> Nat; + rts_collector_instructions : () -> Nat; + rts_heap_size : () -> Nat; + rts_logical_stable_memory_size : () -> Nat; + rts_max_live_size : () -> Nat; + rts_max_stack_size : () -> Nat; + rts_memory_size : () -> Nat; + rts_mutator_instructions : () -> Nat; + rts_reclaimed : () -> Nat; + rts_stable_memory_size : () -> Nat; + rts_total_allocation : () -> Nat; + rts_upgrade_instructions : () -> Nat; + rts_version : () -> Text; + setCandidLimits : + {bias : Nat32; denominator : Nat32; numerator : Nat32} -> (); + setCertifiedData : Blob -> (); + setTimer : (Nat64, Bool, () -> async ()) -> Nat; + shiftLeft : (Nat, Nat32) -> Nat; + shiftRight : (Nat, Nat32) -> Nat; + sin : Float -> Float; + stableMemoryGrow : Nat64 -> Nat64; + stableMemoryLoadBlob : (Nat64, Nat) -> Blob; + stableMemoryLoadFloat : Nat64 -> Float; + stableMemoryLoadInt16 : Nat64 -> Int16; + stableMemoryLoadInt32 : Nat64 -> Int32; + stableMemoryLoadInt64 : Nat64 -> Int64; + stableMemoryLoadInt8 : Nat64 -> Int8; + stableMemoryLoadNat16 : Nat64 -> Nat16; + stableMemoryLoadNat32 : Nat64 -> Nat32; + stableMemoryLoadNat64 : Nat64 -> Nat64; + stableMemoryLoadNat8 : Nat64 -> Nat8; + stableMemorySize : () -> Nat64; + stableMemoryStoreBlob : (Nat64, Blob) -> (); + stableMemoryStoreFloat : (Nat64, Float) -> (); + stableMemoryStoreInt16 : (Nat64, Int16) -> (); + stableMemoryStoreInt32 : (Nat64, Int32) -> (); + stableMemoryStoreInt64 : (Nat64, Int64) -> (); + stableMemoryStoreInt8 : (Nat64, Int8) -> (); + stableMemoryStoreNat16 : (Nat64, Nat16) -> (); + stableMemoryStoreNat32 : (Nat64, Nat32) -> (); + stableMemoryStoreNat64 : (Nat64, Nat64) -> (); + stableMemoryStoreNat8 : (Nat64, Nat8) -> (); + stableVarQuery : () -> shared query () -> async {size : Nat64}; + tan : Float -> Float; + textCompare : (Text, Text) -> Int8; + textLowercase : Text -> Text; + textUppercase : Text -> Text; + time : () -> Nat64; + trap : Text -> None + } +The field stableM is not available. Try something else? diff --git a/test/fail/ok/suggest-long-ai.tc.ret.ok b/test/fail/ok/suggest-long-ai.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-long-ai.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-long.tc.ok b/test/fail/ok/suggest-long.tc.ok new file mode 100644 index 00000000000..733a0b26080 --- /dev/null +++ b/test/fail/ok/suggest-long.tc.ok @@ -0,0 +1,2 @@ +suggest-long.mo:3.1-3.5: type error [M0072], field stableM does not exist in module. +Did you mean field stableMemoryGrow, stableMemorySize, stableMemoryLoadBlob, stableMemoryLoadInt8, stableMemoryLoadNat8, stableMemoryLoadFloat, stableMemoryLoadInt16, stableMemoryLoadInt32, stableMemoryLoadInt64, stableMemoryLoadNat16, stableMemoryLoadNat32, stableMemoryLoadNat64, stableMemoryStoreBlob, stableMemoryStoreInt8, stableMemoryStoreNat8, stableMemoryStoreFloat, stableMemoryStoreInt16, stableMemoryStoreInt32, stableMemoryStoreInt64, stableMemoryStoreNat16, stableMemoryStoreNat32 or stableMemoryStoreNat64? diff --git a/test/fail/ok/suggest-long.tc.ret.ok b/test/fail/ok/suggest-long.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-long.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-short-ai.tc.ok b/test/fail/ok/suggest-short-ai.tc.ok new file mode 100644 index 00000000000..da8382a1215 --- /dev/null +++ b/test/fail/ok/suggest-short-ai.tc.ok @@ -0,0 +1,259 @@ +suggest-short-ai.mo:4.1-4.5: type error [M0072], field s does not exist in type: + module { + type ErrorCode = + { + #call_error : {err_code : Nat32}; + #canister_error; + #canister_reject; + #destination_invalid; + #future : Nat32; + #system_fatal; + #system_transient + }; + Array_init : (Nat, T) -> [var T]; + Array_tabulate : (Nat, Nat -> T) -> [T]; + Ret : () -> T; + Types : + module { + type Any = Any; + type Blob = Blob; + type Bool = Bool; + type Char = Char; + type Error = Error; + type Float = Float; + type Int = Int; + type Int16 = Int16; + type Int32 = Int32; + type Int64 = Int64; + type Int8 = Int8; + type Nat = Nat; + type Nat16 = Nat16; + type Nat32 = Nat32; + type Nat64 = Nat64; + type Nat8 = Nat8; + type None = None; + type Null = Null; + type Principal = Principal; + type Region = Region; + type Text = Text + }; + abs : Int -> Nat; + arccos : Float -> Float; + arcsin : Float -> Float; + arctan : Float -> Float; + arctan2 : (Float, Float) -> Float; + arrayMutToBlob : [var Nat8] -> Blob; + arrayToBlob : [Nat8] -> Blob; + blobCompare : (Blob, Blob) -> Int8; + blobOfPrincipal : Principal -> Blob; + blobToArray : Blob -> [Nat8]; + blobToArrayMut : Blob -> [var Nat8]; + btstInt16 : (Int16, Int16) -> Bool; + btstInt32 : (Int32, Int32) -> Bool; + btstInt64 : (Int64, Int64) -> Bool; + btstInt8 : (Int8, Int8) -> Bool; + btstNat16 : (Nat16, Nat16) -> Bool; + btstNat32 : (Nat32, Nat32) -> Bool; + btstNat64 : (Nat64, Nat64) -> Bool; + btstNat8 : (Nat8, Nat8) -> Bool; + call_raw : (Principal, Text, Blob) -> async Blob; + cancelTimer : Nat -> (); + canisterVersion : () -> Nat64; + charIsAlphabetic : Char -> Bool; + charIsLowercase : Char -> Bool; + charIsUppercase : Char -> Bool; + charIsWhitespace : Char -> Bool; + charToLower : Char -> Char; + charToNat32 : Char -> Nat32; + charToText : Char -> Text; + charToUpper : Char -> Char; + clzInt16 : Int16 -> Int16; + clzInt32 : Int32 -> Int32; + clzInt64 : Int64 -> Int64; + clzInt8 : Int8 -> Int8; + clzNat16 : Nat16 -> Nat16; + clzNat32 : Nat32 -> Nat32; + clzNat64 : Nat64 -> Nat64; + clzNat8 : Nat8 -> Nat8; + cos : Float -> Float; + createActor : (Blob, Blob) -> async Principal; + ctzInt16 : Int16 -> Int16; + ctzInt32 : Int32 -> Int32; + ctzInt64 : Int64 -> Int64; + ctzInt8 : Int8 -> Int8; + ctzNat16 : Nat16 -> Nat16; + ctzNat32 : Nat32 -> Nat32; + ctzNat64 : Nat64 -> Nat64; + ctzNat8 : Nat8 -> Nat8; + cyclesAccept : Nat -> Nat; + cyclesAdd : Nat -> (); + cyclesAvailable : () -> Nat; + cyclesBalance : () -> Nat; + cyclesBurn : Nat -> Nat; + cyclesRefunded : () -> Nat; + debugPrint : Text -> (); + debugPrintChar : Char -> (); + debugPrintInt : Int -> (); + debugPrintNat : Nat -> (); + decodeUtf8 : Blob -> ?Text; + encodeUtf8 : Text -> Blob; + error : Text -> Error; + errorCode : Error -> ErrorCode; + errorMessage : Error -> Text; + exists : (T -> Bool) -> Bool; + exp : Float -> Float; + floatAbs : Float -> Float; + floatCeil : Float -> Float; + floatCopySign : (Float, Float) -> Float; + floatFloor : Float -> Float; + floatMax : (Float, Float) -> Float; + floatMin : (Float, Float) -> Float; + floatNearest : Float -> Float; + floatSqrt : Float -> Float; + floatToFormattedText : (Float, Nat8, Nat8) -> Text; + floatToInt : Float -> Int; + floatToInt64 : Float -> Int64; + floatToText : Float -> Text; + floatTrunc : Float -> Float; + forall : (T -> Bool) -> Bool; + getCandidLimits : + () -> {bias : Nat32; denominator : Nat32; numerator : Nat32}; + getCertificate : () -> ?Blob; + hashBlob : Blob -> Nat32; + idlHash : Text -> Nat32; + int16ToInt : Int16 -> Int; + int16ToInt32 : Int16 -> Int32; + int16ToInt8 : Int16 -> Int8; + int16ToNat16 : Int16 -> Nat16; + int32ToInt : Int32 -> Int; + int32ToInt16 : Int32 -> Int16; + int32ToInt64 : Int32 -> Int64; + int32ToNat32 : Int32 -> Nat32; + int64ToFloat : Int64 -> Float; + int64ToInt : Int64 -> Int; + int64ToInt32 : Int64 -> Int32; + int64ToNat64 : Int64 -> Nat64; + int8ToInt : Int8 -> Int; + int8ToInt16 : Int8 -> Int16; + int8ToNat8 : Int8 -> Nat8; + intToFloat : Int -> Float; + intToInt16 : Int -> Int16; + intToInt16Wrap : Int -> Int16; + intToInt32 : Int -> Int32; + intToInt32Wrap : Int -> Int32; + intToInt64 : Int -> Int64; + intToInt64Wrap : Int -> Int64; + intToInt8 : Int -> Int8; + intToInt8Wrap : Int -> Int8; + intToNat16Wrap : Int -> Nat16; + intToNat32Wrap : Int -> Nat32; + intToNat64Wrap : Int -> Nat64; + intToNat8Wrap : Int -> Nat8; + isController : Principal -> Bool; + log : Float -> Float; + nat16ToInt16 : Nat16 -> Int16; + nat16ToNat : Nat16 -> Nat; + nat16ToNat32 : Nat16 -> Nat32; + nat16ToNat8 : Nat16 -> Nat8; + nat32ToChar : Nat32 -> Char; + nat32ToInt32 : Nat32 -> Int32; + nat32ToNat : Nat32 -> Nat; + nat32ToNat16 : Nat32 -> Nat16; + nat32ToNat64 : Nat32 -> Nat64; + nat64ToInt64 : Nat64 -> Int64; + nat64ToNat : Nat64 -> Nat; + nat64ToNat32 : Nat64 -> Nat32; + nat8ToInt8 : Nat8 -> Int8; + nat8ToNat : Nat8 -> Nat; + nat8ToNat16 : Nat8 -> Nat16; + natToNat16 : Nat -> Nat16; + natToNat32 : Nat -> Nat32; + natToNat64 : Nat -> Nat64; + natToNat8 : Nat -> Nat8; + performanceCounter : Nat32 -> Nat64; + popcntInt16 : Int16 -> Int16; + popcntInt32 : Int32 -> Int32; + popcntInt64 : Int64 -> Int64; + popcntInt8 : Int8 -> Int8; + popcntNat16 : Nat16 -> Nat16; + popcntNat32 : Nat32 -> Nat32; + popcntNat64 : Nat64 -> Nat64; + popcntNat8 : Nat8 -> Nat8; + principalOfActor : (actor {}) -> Principal; + principalOfBlob : Blob -> Principal; + regionGrow : (Region, Nat64) -> Nat64; + regionId : Region -> Nat; + regionLoadBlob : (Region, Nat64, Nat) -> Blob; + regionLoadFloat : (Region, Nat64) -> Float; + regionLoadInt16 : (Region, Nat64) -> Int16; + regionLoadInt32 : (Region, Nat64) -> Int32; + regionLoadInt64 : (Region, Nat64) -> Int64; + regionLoadInt8 : (Region, Nat64) -> Int8; + regionLoadNat16 : (Region, Nat64) -> Nat16; + regionLoadNat32 : (Region, Nat64) -> Nat32; + regionLoadNat64 : (Region, Nat64) -> Nat64; + regionLoadNat8 : (Region, Nat64) -> Nat8; + regionNew : () -> Region; + regionSize : Region -> Nat64; + regionStoreBlob : (Region, Nat64, Blob) -> (); + regionStoreFloat : (Region, Nat64, Float) -> (); + regionStoreInt16 : (Region, Nat64, Int16) -> (); + regionStoreInt32 : (Region, Nat64, Int32) -> (); + regionStoreInt64 : (Region, Nat64, Int64) -> (); + regionStoreInt8 : (Region, Nat64, Int8) -> (); + regionStoreNat16 : (Region, Nat64, Nat16) -> (); + regionStoreNat32 : (Region, Nat64, Nat32) -> (); + regionStoreNat64 : (Region, Nat64, Nat64) -> (); + regionStoreNat8 : (Region, Nat64, Nat8) -> (); + rts_callback_table_count : () -> Nat; + rts_callback_table_size : () -> Nat; + rts_collector_instructions : () -> Nat; + rts_heap_size : () -> Nat; + rts_logical_stable_memory_size : () -> Nat; + rts_max_live_size : () -> Nat; + rts_max_stack_size : () -> Nat; + rts_memory_size : () -> Nat; + rts_mutator_instructions : () -> Nat; + rts_reclaimed : () -> Nat; + rts_stable_memory_size : () -> Nat; + rts_total_allocation : () -> Nat; + rts_upgrade_instructions : () -> Nat; + rts_version : () -> Text; + setCandidLimits : + {bias : Nat32; denominator : Nat32; numerator : Nat32} -> (); + setCertifiedData : Blob -> (); + setTimer : (Nat64, Bool, () -> async ()) -> Nat; + shiftLeft : (Nat, Nat32) -> Nat; + shiftRight : (Nat, Nat32) -> Nat; + sin : Float -> Float; + stableMemoryGrow : Nat64 -> Nat64; + stableMemoryLoadBlob : (Nat64, Nat) -> Blob; + stableMemoryLoadFloat : Nat64 -> Float; + stableMemoryLoadInt16 : Nat64 -> Int16; + stableMemoryLoadInt32 : Nat64 -> Int32; + stableMemoryLoadInt64 : Nat64 -> Int64; + stableMemoryLoadInt8 : Nat64 -> Int8; + stableMemoryLoadNat16 : Nat64 -> Nat16; + stableMemoryLoadNat32 : Nat64 -> Nat32; + stableMemoryLoadNat64 : Nat64 -> Nat64; + stableMemoryLoadNat8 : Nat64 -> Nat8; + stableMemorySize : () -> Nat64; + stableMemoryStoreBlob : (Nat64, Blob) -> (); + stableMemoryStoreFloat : (Nat64, Float) -> (); + stableMemoryStoreInt16 : (Nat64, Int16) -> (); + stableMemoryStoreInt32 : (Nat64, Int32) -> (); + stableMemoryStoreInt64 : (Nat64, Int64) -> (); + stableMemoryStoreInt8 : (Nat64, Int8) -> (); + stableMemoryStoreNat16 : (Nat64, Nat16) -> (); + stableMemoryStoreNat32 : (Nat64, Nat32) -> (); + stableMemoryStoreNat64 : (Nat64, Nat64) -> (); + stableMemoryStoreNat8 : (Nat64, Nat8) -> (); + stableVarQuery : () -> shared query () -> async {size : Nat64}; + tan : Float -> Float; + textCompare : (Text, Text) -> Int8; + textLowercase : Text -> Text; + textUppercase : Text -> Text; + time : () -> Nat64; + trap : Text -> None + } +The field s is not available. Try something else? diff --git a/test/fail/ok/suggest-short-ai.tc.ret.ok b/test/fail/ok/suggest-short-ai.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-short-ai.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-short.tc.ok b/test/fail/ok/suggest-short.tc.ok new file mode 100644 index 00000000000..c2166ac4774 --- /dev/null +++ b/test/fail/ok/suggest-short.tc.ok @@ -0,0 +1,2 @@ +suggest-short.mo:3.1-3.5: type error [M0072], field s does not exist in module. +Did you mean field sin, setTimer, shiftLeft, shiftRight, stableVarQuery, setCandidLimits, setCertifiedData, stableMemoryGrow, stableMemorySize, stableMemoryLoadBlob, stableMemoryLoadInt8, stableMemoryLoadNat8, stableMemoryLoadFloat, stableMemoryLoadInt16, stableMemoryLoadInt32, stableMemoryLoadInt64, stableMemoryLoadNat16, stableMemoryLoadNat32, stableMemoryLoadNat64, stableMemoryStoreBlob, stableMemoryStoreInt8, stableMemoryStoreNat8, stableMemoryStoreFloat, stableMemoryStoreInt16, stableMemoryStoreInt32, stableMemoryStoreInt64, stableMemoryStoreNat16, stableMemoryStoreNat32 or stableMemoryStoreNat64? diff --git a/test/fail/ok/suggest-short.tc.ret.ok b/test/fail/ok/suggest-short.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-short.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-type-ai.tc.ok b/test/fail/ok/suggest-type-ai.tc.ok new file mode 100644 index 00000000000..6735a8a3042 --- /dev/null +++ b/test/fail/ok/suggest-type-ai.tc.ok @@ -0,0 +1,25 @@ +suggest-type-ai.mo:4.21-4.24: type error [M0030], type field Num does not exist in type + module { + type Any = Any; + type Blob = Blob; + type Bool = Bool; + type Char = Char; + type Error = Error; + type Float = Float; + type Int = Int; + type Int16 = Int16; + type Int32 = Int32; + type Int64 = Int64; + type Int8 = Int8; + type Nat = Nat; + type Nat16 = Nat16; + type Nat32 = Nat32; + type Nat64 = Nat64; + type Nat8 = Nat8; + type None = None; + type Null = Null; + type Principal = Principal; + type Region = Region; + type Text = Text + } +The type field Num is not available. Try something else? diff --git a/test/fail/ok/suggest-type-ai.tc.ret.ok b/test/fail/ok/suggest-type-ai.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-type-ai.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/ok/suggest-type.tc.ok b/test/fail/ok/suggest-type.tc.ok new file mode 100644 index 00000000000..1333e4eaceb --- /dev/null +++ b/test/fail/ok/suggest-type.tc.ok @@ -0,0 +1,24 @@ +suggest-type.mo:3.21-3.24: type error [M0030], type field Num does not exist in type + module { + type Any = Any; + type Blob = Blob; + type Bool = Bool; + type Char = Char; + type Error = Error; + type Float = Float; + type Int = Int; + type Int16 = Int16; + type Int32 = Int32; + type Int64 = Int64; + type Int8 = Int8; + type Nat = Nat; + type Nat16 = Nat16; + type Nat32 = Nat32; + type Nat64 = Nat64; + type Nat8 = Nat8; + type None = None; + type Null = Null; + type Principal = Principal; + type Region = Region; + type Text = Text + } diff --git a/test/fail/ok/suggest-type.tc.ret.ok b/test/fail/ok/suggest-type.tc.ret.ok new file mode 100644 index 00000000000..69becfa16f9 --- /dev/null +++ b/test/fail/ok/suggest-type.tc.ret.ok @@ -0,0 +1 @@ +Return code 1 diff --git a/test/fail/suggest-label-ai.mo b/test/fail/suggest-label-ai.mo new file mode 100644 index 00000000000..1693da5a3ca --- /dev/null +++ b/test/fail/suggest-label-ai.mo @@ -0,0 +1,4 @@ +//MOC-FLAG --ai-errors +label foo { + break fo; +}; diff --git a/test/fail/suggest-label.mo b/test/fail/suggest-label.mo new file mode 100644 index 00000000000..60b3e1d7386 --- /dev/null +++ b/test/fail/suggest-label.mo @@ -0,0 +1,3 @@ +label foo { + break fo; +}; diff --git a/test/fail/suggest-local-ai.mo b/test/fail/suggest-local-ai.mo new file mode 100644 index 00000000000..462353bd86e --- /dev/null +++ b/test/fail/suggest-local-ai.mo @@ -0,0 +1,3 @@ +//MOC-FLAG --ai-errors +let xxx = 1; +x; diff --git a/test/fail/suggest-local-type-ai.mo b/test/fail/suggest-local-type-ai.mo new file mode 100644 index 00000000000..ebfb4018f26 --- /dev/null +++ b/test/fail/suggest-local-type-ai.mo @@ -0,0 +1,3 @@ +//MOC-FLAG --ai-errors +type Foo = Int; +type Zap = [Fo]; diff --git a/test/fail/suggest-local-type.mo b/test/fail/suggest-local-type.mo new file mode 100644 index 00000000000..0ee464999a1 --- /dev/null +++ b/test/fail/suggest-local-type.mo @@ -0,0 +1,2 @@ +type Foo = Int; +type Zap = [Fo]; diff --git a/test/fail/suggest-local.mo b/test/fail/suggest-local.mo new file mode 100644 index 00000000000..e5ec33410dc --- /dev/null +++ b/test/fail/suggest-local.mo @@ -0,0 +1,2 @@ +let xxx = 1; +x; diff --git a/test/fail/suggest-long-ai.mo b/test/fail/suggest-long-ai.mo new file mode 100644 index 00000000000..9666b3dd3b4 --- /dev/null +++ b/test/fail/suggest-long-ai.mo @@ -0,0 +1,4 @@ +//MOC-FLAG --ai-errors +import Prim "mo:⛔"; + +Prim.stableM; diff --git a/test/fail/suggest-long.mo b/test/fail/suggest-long.mo new file mode 100644 index 00000000000..36ade663858 --- /dev/null +++ b/test/fail/suggest-long.mo @@ -0,0 +1,3 @@ +import Prim "mo:⛔"; + +Prim.stableM; diff --git a/test/fail/suggest-short-ai.mo b/test/fail/suggest-short-ai.mo new file mode 100644 index 00000000000..0b557e72929 --- /dev/null +++ b/test/fail/suggest-short-ai.mo @@ -0,0 +1,4 @@ +//MOC-FLAG --ai-errors +import Prim "mo:⛔"; + +Prim.s; diff --git a/test/fail/suggest-short.mo b/test/fail/suggest-short.mo new file mode 100644 index 00000000000..d937da6e728 --- /dev/null +++ b/test/fail/suggest-short.mo @@ -0,0 +1,3 @@ +import Prim "mo:⛔"; + +Prim.s; diff --git a/test/fail/suggest-type-ai.mo b/test/fail/suggest-type-ai.mo new file mode 100644 index 00000000000..c43e3f30bda --- /dev/null +++ b/test/fail/suggest-type-ai.mo @@ -0,0 +1,4 @@ +//MOC-FLAG --ai-errors +import Prim "mo:⛔"; + +type T = Prim.Types.Num; diff --git a/test/fail/suggest-type.mo b/test/fail/suggest-type.mo new file mode 100644 index 00000000000..2fe6d14f8cb --- /dev/null +++ b/test/fail/suggest-type.mo @@ -0,0 +1,3 @@ +import Prim "mo:⛔"; + +type T = Prim.Types.Num;