From 72f346871c8e7fd6df2d6b67262fd7369e354aff Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 23 Sep 2019 08:08:34 -0700 Subject: [PATCH] Handle `JSON.stringify(undefined)` Turns out that `JSON.stringify(undefined)` doesn't actually return a string, it returns `undefined`! If we're requested to serialize `undefined` into JSON instead just interpret it as `null` which should have the expected semantics of serving as a placeholder for `None`. Closes #1778 --- crates/cli-support/src/js/mod.rs | 6 +++++- tests/wasm/js_objects.rs | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 5364decc7..33ee39984 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -2626,7 +2626,11 @@ impl<'a> Context<'a> { Intrinsic::JsonSerialize => { assert_eq!(args.len(), 1); - format!("JSON.stringify({})", args[0]) + // Turns out `JSON.stringify(undefined) === undefined`, so if + // we're passed `undefined` reinterpret it as `null` for JSON + // purposes. + prelude.push_str(&format!("const obj = {};\n", args[0])); + "JSON.stringify(obj === undefined ? null : obj)".to_string() } Intrinsic::AnyrefHeapLiveCount => { diff --git a/tests/wasm/js_objects.rs b/tests/wasm/js_objects.rs index 3c0ea3ebe..38263e00a 100644 --- a/tests/wasm/js_objects.rs +++ b/tests/wasm/js_objects.rs @@ -144,4 +144,5 @@ fn serde() { assert_eq!(foo.d.a, 4); assert_eq!(JsValue::from("bar").into_serde::().unwrap(), "bar"); + assert_eq!(JsValue::undefined().into_serde::().ok(), None); }