diff --git a/CHANGELOG.md b/CHANGELOG.md index edd491c6e1..16c83840ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ #### :bug: Bug fix - Fix code generation for emojis in polyvars and labels. https://github.com/rescript-lang/rescript/pull/7853 +- Fix crash with `@get` on external of type `unit => 'a`. https://github.com/rescript-lang/rescript/pull/7866 #### :memo: Documentation diff --git a/compiler/core/lam_compile_external_call.ml b/compiler/core/lam_compile_external_call.ml index 34cdcbd9d0..bf7a245673 100644 --- a/compiler/core/lam_compile_external_call.ml +++ b/compiler/core/lam_compile_external_call.ml @@ -421,7 +421,11 @@ let translate_ffi ?(transformed_jsx = false) (cxt : Lam_compile_context.t) | [obj] -> let obj = translate_scoped_access scopes obj in E.dot obj name - | _ -> assert false + | _ -> + (* This should have been caught in the frontend validation. *) + invalid_arg + "Internal compiler error: @get external called with wrong number of \ + arguments. Expected exactly one object argument." (* Note these assertion happens in call site *)) | Js_set {js_set_name = name; js_set_scopes = scopes} -> ( (* assert (js_splice = false) ; *) diff --git a/compiler/frontend/ast_external_process.ml b/compiler/frontend/ast_external_process.ml index a32bc5e8e8..b4efc128ad 100644 --- a/compiler/frontend/ast_external_process.ml +++ b/compiler/frontend/ast_external_process.ml @@ -899,7 +899,12 @@ let external_desc_of_non_obj (loc : Location.t) (st : external_desc) tagged_template = _; } -> if arg_type_specs_length = 1 then - Js_get {js_get_name = name; js_get_scopes = scopes} + (* Check if the first argument is unit, which is invalid for @get *) + match arg_type_specs with + | [{arg_type = Extern_unit}] -> + Location.raise_errorf ~loc + "Ill defined attribute %@get (unit argument is not allowed)" + | _ -> Js_get {js_get_name = name; js_get_scopes = scopes} else Location.raise_errorf ~loc "Ill defined attribute %@get (only one argument)" diff --git a/tests/build_tests/super_errors/expected/get_unit_arg.res.expected b/tests/build_tests/super_errors/expected/get_unit_arg.res.expected new file mode 100644 index 0000000000..6957ae45ab --- /dev/null +++ b/tests/build_tests/super_errors/expected/get_unit_arg.res.expected @@ -0,0 +1,12 @@ + + We've found a bug for you! + /.../fixtures/get_unit_arg.res:2:1-3:36 + + 1 │ // Test case for issue #7676 - @get external with unit => 'a should give + │ proper error + 2 │ @get + 3 │ external foo: unit => string = "foo" + 4 │ + 5 │ let x = foo() + + Ill defined attribute @get (unit argument is not allowed) \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/get_unit_arg.res b/tests/build_tests/super_errors/fixtures/get_unit_arg.res new file mode 100644 index 0000000000..1475a23060 --- /dev/null +++ b/tests/build_tests/super_errors/fixtures/get_unit_arg.res @@ -0,0 +1,5 @@ +// Test case for issue #7676 - @get external with unit => 'a should give proper error +@get +external foo: unit => string = "foo" + +let x = foo()