Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(compiler): Improve unsafe equality warning #1892

Merged
merged 8 commits into from
Aug 22, 2023
29 changes: 29 additions & 0 deletions compiler/src/typed/typed_well_formedness.re
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ let rec exp_is_wasm_unsafe = ({exp_type}) => {
};
type_is_wasm_unsafe(exp_type);
};
let rec resolve_unsafe_type = ({exp_type}) => {
let rec type_is_wasm_unsafe = t => {
switch (t.desc) {
| TTyConstr(path, _, _) =>
switch (path) {
| t when t == Builtin_types.path_wasmi32 => Some("WasmI32")
| t when t == Builtin_types.path_wasmi64 => Some("WasmI64")
| t when t == Builtin_types.path_wasmf32 => Some("WasmF32")
| t when t == Builtin_types.path_wasmf64 => Some("WasmI64")
| _ => None
}
| TTyLink(t) => type_is_wasm_unsafe(t)
| _ => None
phated marked this conversation as resolved.
Show resolved Hide resolved
};
};
type_is_wasm_unsafe(exp_type);
};

let is_marked_unsafe = attrs => {
// Disable_gc implies Unsafe
Expand Down Expand Up @@ -228,9 +245,21 @@ module WellFormednessArg: TypedtreeIter.IteratorArgument = {
)
when func == "==" || func == "!=" =>
if (List.exists(((_, arg)) => exp_is_wasm_unsafe(arg), args)) {
let typeName =
switch (args) {
| [(_, arg), _] =>
switch (resolve_unsafe_type(arg)) {
| Some(typeName) => typeName
// This should never be hit
| None => failwith("Impossible: exp_is_wasm_unsafe > typeName")
phated marked this conversation as resolved.
Show resolved Hide resolved
}
| _ => "(WasmI32 | WasmI64 | WasmF32 | WasmF64)"
};
let warning =
Grain_utils.Warnings.FuncWasmUnsafe(
Printf.sprintf("Pervasives.(%s)", func),
Printf.sprintf("%s.(%s)", typeName, func),
typeName,
);
if (Grain_utils.Warnings.is_active(warning)) {
Grain_parsing.Location.prerr_warning(exp_loc, warning);
Expand Down
14 changes: 9 additions & 5 deletions compiler/src/utils/warnings.re
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type t =
| UnreachableCase
| ShadowConstructor(string)
| NoCmiFile(string, option(string))
| FuncWasmUnsafe(string)
| FuncWasmUnsafe(string, string, string)
| FromNumberLiteralI32(string)
| FromNumberLiteralI64(string)
| FromNumberLiteralU32(string)
Expand Down Expand Up @@ -52,7 +52,7 @@ let number =
| NoCmiFile(_) => 14
| NonClosedRecordPattern(_) => 15
| UnusedExtension => 16
| FuncWasmUnsafe(_) => 17
| FuncWasmUnsafe(_, _, _) => 17
| FromNumberLiteralI32(_) => 18
| FromNumberLiteralI64(_) => 19
| FromNumberLiteralU32(_) => 20
Expand Down Expand Up @@ -119,10 +119,14 @@ let message =
)
| NonClosedRecordPattern(s) =>
"the following fields are missing from the record pattern: " ++ s
| FuncWasmUnsafe(func) =>
| FuncWasmUnsafe(func, f, m) =>
"it looks like you are using "
++ func
++ " on two unsafe Wasm values here.\nThis is generally unsafe and will cause errors. Use one of the equivalent functions in `WasmI32`, `WasmI64`, `WasmF32`, or `WasmF64` instead."
++ " on two unsafe Wasm values here.\nThis is generally unsafe and will cause errors. Use "
++ f
++ " from the `"
++ m
++ "` module the instead."
| FromNumberLiteralI32(n) =>
Printf.sprintf(
"it looks like you are calling Int32.fromNumber() with a constant number. Try using the literal syntax (e.g. `%sl`) instead.",
Expand Down Expand Up @@ -195,7 +199,7 @@ let defaults = [
UnreachableCase,
ShadowConstructor(""),
NoCmiFile("", None),
FuncWasmUnsafe(""),
FuncWasmUnsafe("", "", ""),
FromNumberLiteralI32(""),
FromNumberLiteralI64(""),
FromNumberLiteralU32(""),
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/utils/warnings.rei
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type t =
| UnreachableCase
| ShadowConstructor(string)
| NoCmiFile(string, option(string))
| FuncWasmUnsafe(string)
| FuncWasmUnsafe(string, string, string)
| FromNumberLiteralI32(string)
| FromNumberLiteralI64(string)
| FromNumberLiteralU32(string)
Expand Down
Loading