From bf9bd790e655f9a16d0018c845b1401fda5ed2f5 Mon Sep 17 00:00:00 2001 From: Chris Rybicki Date: Mon, 19 Aug 2024 11:54:29 -0400 Subject: [PATCH 1/3] fix(compiler): improve error diagnostic for invalid string concatenations --- examples/tests/invalid/stringify.test.w | 8 ++++++++ libs/wingc/src/type_check.rs | 25 ++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/tests/invalid/stringify.test.w b/examples/tests/invalid/stringify.test.w index 9f2231e8b3f..cc5891e2099 100644 --- a/examples/tests/invalid/stringify.test.w +++ b/examples/tests/invalid/stringify.test.w @@ -7,9 +7,17 @@ struct Foo { let foo: Foo = {bar: b, baz: "hello"}; +let x = 42; + log("hello {b}"); // ^ Expected type to be "stringable", but got "B" instead +log("value: " + x); +// ^ Binary operator '+' cannot be applied to operands of type 'str' and 'num' + +log(x + " is the value"); +// ^ Binary operator '+' cannot be applied to operands of type 'str' and 'num' + let x: str? = nil; log("{x}"); // ^ Expected type to be "stringable", but got "str?" instead diff --git a/libs/wingc/src/type_check.rs b/libs/wingc/src/type_check.rs index 0bd844934f7..4cf8d53b9d6 100644 --- a/libs/wingc/src/type_check.rs +++ b/libs/wingc/src/type_check.rs @@ -2296,17 +2296,24 @@ It should primarily be used in preflight or in inflights that are guaranteed to } else { // If any of the types are unresolved (error) then don't report this assuming the error has already been reported if !ltype.is_unresolved() && !rtype.is_unresolved() { - self.spanned_error( + let mut hints = vec![]; + // If one of the operands is a string type, add a hint to use string interpolation + if ltype.is_subtype_of(&self.types.string()) || rtype.is_subtype_of(&self.types.string()) { + hints.push("Consider using string interpolation: \"Hello, {name}\"".to_string()); + } + + self.spanned_error_with_hints( exp, format!( - "Binary operator '+' cannot be applied to operands of type '{}' and '{}'; only ({}, {}) and ({}, {}) are supported", - ltype, - rtype, - self.types.number(), - self.types.number(), - self.types.string(), - self.types.string(), - ), + "Binary operator '+' cannot be applied to operands of type '{}' and '{}'; only ({}, {}) and ({}, {}) are supported", + ltype, + rtype, + self.types.number(), + self.types.number(), + self.types.string(), + self.types.string(), + ), + &hints, ); } self.resolved_error() From 718eb48895cadebd2eb3a05e58f0b0cb2a115f11 Mon Sep 17 00:00:00 2001 From: Chris Rybicki Date: Mon, 19 Aug 2024 11:59:17 -0400 Subject: [PATCH 2/3] update example --- examples/tests/invalid/stringify.test.w | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/tests/invalid/stringify.test.w b/examples/tests/invalid/stringify.test.w index cc5891e2099..0cd33606a59 100644 --- a/examples/tests/invalid/stringify.test.w +++ b/examples/tests/invalid/stringify.test.w @@ -7,17 +7,9 @@ struct Foo { let foo: Foo = {bar: b, baz: "hello"}; -let x = 42; - log("hello {b}"); // ^ Expected type to be "stringable", but got "B" instead -log("value: " + x); -// ^ Binary operator '+' cannot be applied to operands of type 'str' and 'num' - -log(x + " is the value"); -// ^ Binary operator '+' cannot be applied to operands of type 'str' and 'num' - let x: str? = nil; log("{x}"); // ^ Expected type to be "stringable", but got "str?" instead @@ -27,3 +19,11 @@ log(b); log(foo); // ^ Expected type to be "stringable", but got "Foo" instead + +let z = 42; + +log("value: " + z); +// ^ Binary operator '+' cannot be applied to operands of type 'str' and 'num' + +log(z + " is the value"); +// ^ Binary operator '+' cannot be applied to operands of type 'str' and 'num' From ba0e2535e620a1a87449076675987e64c7470d3a Mon Sep 17 00:00:00 2001 From: "monada-bot[bot]" Date: Mon, 19 Aug 2024 16:13:02 +0000 Subject: [PATCH 3/3] chore: self mutation (e2e-2of2.diff) Signed-off-by: monada-bot[bot] --- tools/hangar/__snapshots__/invalid.ts.snap | 32 ++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap index 3b58593b615..e0ec8e10f2e 100644 --- a/tools/hangar/__snapshots__/invalid.ts.snap +++ b/tools/hangar/__snapshots__/invalid.ts.snap @@ -988,6 +988,8 @@ error: Binary operator '+' cannot be applied to operands of type 'num' and 'str' | 185 | 2 + "2"; | ^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Expected type to be "num", but got "str" instead @@ -1002,6 +1004,8 @@ error: Binary operator '+' cannot be applied to operands of type 'num' and 'str' | 198 | 2 + "2"; | ^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Expected type to be "str", but got "num" instead @@ -1016,6 +1020,8 @@ error: Binary operator '+' cannot be applied to operands of type 'num' and 'str' | 210 | 2 + "2"; | ^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Expected type to be "num", but got "str" instead @@ -1030,6 +1036,8 @@ error: Binary operator '+' cannot be applied to operands of type 'num' and 'str' | 221 | 2 + "2"; | ^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Expected type to be "str", but got "num" instead @@ -2307,6 +2315,8 @@ error: Binary operator '+' cannot be applied to operands of type 'num' and 'str' | 36 | let var x = 3 + "hello"; | ^^^^^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Unsupported reassignment of element of type unresolved @@ -4629,6 +4639,24 @@ error: Expected type to be "stringable", but got "Foo" instead | = hint: str, num, bool, json, and enums are stringable + +error: Binary operator '+' cannot be applied to operands of type 'str' and 'num'; only (num, num) and (str, str) are supported + --> ../../../examples/tests/invalid/stringify.test.w:25:5 + | +25 | log("value: " + z); + | ^^^^^^^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" + + +error: Binary operator '+' cannot be applied to operands of type 'num' and 'str'; only (num, num) and (str, str) are supported + --> ../../../examples/tests/invalid/stringify.test.w:28:5 + | +28 | log(z + " is the value"); + | ^^^^^^^^^^^^^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" + Tests 1 failed (1) Snapshots 1 skipped Test Files 1 failed (1) @@ -4974,6 +5002,8 @@ exports[`types_strings_arithmetic.test.w 1`] = ` | 1 | let e1 = 2 + "2"; | ^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Expected type to be "num", but got "str" instead @@ -5188,6 +5218,8 @@ error: Binary operator '+' cannot be applied to operands of type 'num' and 'str' | 20 | this.bucket.assert(2 + "2"); | ^^^^^^^ + | + = hint: Consider using string interpolation: "Hello, {name}" error: Member "assert" does not exist in "Bucket"