diff --git a/feature_tests/js/api/MyStruct.mjs b/feature_tests/js/api/MyStruct.mjs index c28658d61..02a17b9b3 100644 --- a/feature_tests/js/api/MyStruct.mjs +++ b/feature_tests/js/api/MyStruct.mjs @@ -134,7 +134,7 @@ export class MyStruct { try { if (!diplomatReceive.resultFlag) { const cause = new MyZst(); - throw new Error('MyZst', { cause }); + throw new globalThis.Error('MyZst', { cause }); } } diff --git a/feature_tests/js/api/ResultOpaque.mjs b/feature_tests/js/api/ResultOpaque.mjs index 6f50055f5..4ec1b1ae3 100644 --- a/feature_tests/js/api/ResultOpaque.mjs +++ b/feature_tests/js/api/ResultOpaque.mjs @@ -36,7 +36,7 @@ export class ResultOpaque { try { if (!diplomatReceive.resultFlag) { const cause = ErrorEnum[Array.from(ErrorEnum.values.keys())[diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer)]]; - throw new Error('ErrorEnum: ' + cause.value, { cause }); + throw new globalThis.Error('ErrorEnum: ' + cause.value, { cause }); } return new ResultOpaque(diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []); } @@ -54,7 +54,7 @@ export class ResultOpaque { try { if (!diplomatReceive.resultFlag) { const cause = ErrorEnum[Array.from(ErrorEnum.values.keys())[diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer)]]; - throw new Error('ErrorEnum: ' + cause.value, { cause }); + throw new globalThis.Error('ErrorEnum: ' + cause.value, { cause }); } return new ResultOpaque(diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []); } @@ -72,7 +72,7 @@ export class ResultOpaque { try { if (!diplomatReceive.resultFlag) { const cause = ErrorEnum[Array.from(ErrorEnum.values.keys())[diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer)]]; - throw new Error('ErrorEnum: ' + cause.value, { cause }); + throw new globalThis.Error('ErrorEnum: ' + cause.value, { cause }); } return new ResultOpaque(diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []); } @@ -107,7 +107,7 @@ export class ResultOpaque { try { if (!diplomatReceive.resultFlag) { const cause = new ErrorStruct()._fromFFI(diplomatReceive.buffer); - throw new Error('ErrorStruct: ' + cause.toString(), { cause }); + throw new globalThis.Error('ErrorStruct: ' + cause.toString(), { cause }); } return new ResultOpaque(diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []); } @@ -125,7 +125,7 @@ export class ResultOpaque { try { if (!diplomatReceive.resultFlag) { const cause = new ResultOpaque(diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []); - throw new Error('ResultOpaque: ' + cause.toString(), { cause }); + throw new globalThis.Error('ResultOpaque: ' + cause.toString(), { cause }); } } @@ -160,7 +160,7 @@ export class ResultOpaque { try { if (!diplomatReceive.resultFlag) { const cause = new ResultOpaque(diplomatRuntime.ptrRead(wasm, diplomatReceive.buffer), []); - throw new Error('ResultOpaque: ' + cause.toString(), { cause }); + throw new globalThis.Error('ResultOpaque: ' + cause.toString(), { cause }); } return ErrorEnum[Array.from(ErrorEnum.values.keys())[diplomatRuntime.enumDiscriminant(wasm, diplomatReceive.buffer)]]; } diff --git a/tool/src/js/formatter.rs b/tool/src/js/formatter.rs index fe7bc0d7d..d6a4f58b8 100644 --- a/tool/src/js/formatter.rs +++ b/tool/src/js/formatter.rs @@ -37,12 +37,16 @@ const RESERVED: &[&str] = &[ "true", "try", "typeof", + "undefined", "var", "void", "while", "with", ]; +/// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects +const RESERVED_TYPES: &[&str] = &["Infinity", "NaN"]; + /// Helper class for us to format JS identifiers from the HIR. pub(crate) struct JSFormatter<'tcx> { /// Per [`CFormatter`]'s documentation we use it for support. @@ -60,10 +64,16 @@ impl<'tcx> JSFormatter<'tcx> { pub fn fmt_type_name(&self, id: TypeId) -> Cow<'tcx, str> { let type_def = self.tcx.resolve_type(id); - type_def + let name = type_def .attrs() .rename - .apply(type_def.name().as_str().into()) + .apply(type_def.name().as_str().into()); + + if RESERVED_TYPES.contains(&&*name) || RESERVED.contains(&&*name) { + panic!("{name} is not an allowed type in JS. Please rename.") + } + + name } pub fn fmt_file_name_extensionless(&self, type_name: &str) -> String { diff --git a/tool/src/js/type_generation/converter.rs b/tool/src/js/type_generation/converter.rs index bd51d77bf..88c9c139c 100644 --- a/tool/src/js/type_generation/converter.rs +++ b/tool/src/js/type_generation/converter.rs @@ -438,7 +438,7 @@ impl<'jsctx, 'tcx> TyGenContext<'jsctx, 'tcx> { let cause = self.gen_c_to_js_for_type(e, receive_deref, &method.lifetime_env); format!( - "const cause = {cause};\n throw new Error({message}, {{ cause }})", + "const cause = {cause};\n throw new globalThis.Error({message}, {{ cause }})", message = match e { Type::Enum(..) => format!("'{type_name}: ' + cause.value"), Type::Struct(s) if match s.resolve(self.tcx) {