From a1088275b9ff2e8514071b6abe5c397ae9857524 Mon Sep 17 00:00:00 2001 From: shadowninja55 <49539636+shadowninja55@users.noreply.github.com> Date: Fri, 9 Jul 2021 17:00:12 -0400 Subject: [PATCH] checker: prohibit illegal types in string interpolation literals (#10705) --- vlib/v/checker/check_types.v | 6 ++++++ vlib/v/checker/tests/bad_types_in_string_inter_lit.out | 8 ++++++++ vlib/v/checker/tests/bad_types_in_string_inter_lit.vv | 2 ++ vlib/v/checker/tests/unknown_method_suggest_name.out | 6 ++++++ .../v/checker/tests/unknown_struct_field_suggest_name.out | 7 +++++++ 5 files changed, 29 insertions(+) create mode 100644 vlib/v/checker/tests/bad_types_in_string_inter_lit.out create mode 100644 vlib/v/checker/tests/bad_types_in_string_inter_lit.vv diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index c4bac909c..e70e29f43 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -437,6 +437,12 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Typ c.inside_println_arg = true for i, expr in node.exprs { ftyp := c.expr(expr) + if ftyp == ast.void_type { + c.error('expression does not return a value', expr.position()) + } else if ftyp == ast.char_type && ftyp.nr_muls() == 0 { + c.error('expression returning type `char` cannot be used in string interpolation directly, print its address or cast it to an integer instead', + expr.position()) + } c.fail_if_unreadable(expr, ftyp, 'interpolation object') node.expr_types << ftyp typ := c.table.unalias_num_type(ftyp) diff --git a/vlib/v/checker/tests/bad_types_in_string_inter_lit.out b/vlib/v/checker/tests/bad_types_in_string_inter_lit.out new file mode 100644 index 000000000..e6a1cac0a --- /dev/null +++ b/vlib/v/checker/tests/bad_types_in_string_inter_lit.out @@ -0,0 +1,8 @@ +vlib/v/checker/tests/bad_types_in_string_inter_lit.vv:1:12: error: expression does not return a value + 1 | println('${exit(0)}') + | ~~~~~~~ + 2 | println('${char(48)}') +vlib/v/checker/tests/bad_types_in_string_inter_lit.vv:2:12: error: expression returning type `char` cannot be used in string interpolation directly, print its address or cast it to an integer instead + 1 | println('${exit(0)}') + 2 | println('${char(48)}') + | ~~~~~~~~ diff --git a/vlib/v/checker/tests/bad_types_in_string_inter_lit.vv b/vlib/v/checker/tests/bad_types_in_string_inter_lit.vv new file mode 100644 index 000000000..e4dc26c52 --- /dev/null +++ b/vlib/v/checker/tests/bad_types_in_string_inter_lit.vv @@ -0,0 +1,2 @@ +println('${exit(0)}') +println('${char(48)}') diff --git a/vlib/v/checker/tests/unknown_method_suggest_name.out b/vlib/v/checker/tests/unknown_method_suggest_name.out index aadc8f40a..f80de0946 100644 --- a/vlib/v/checker/tests/unknown_method_suggest_name.out +++ b/vlib/v/checker/tests/unknown_method_suggest_name.out @@ -14,3 +14,9 @@ Did you mean `translate`? | ~~~~~~~~~~~~ 28 | println('p: $p') 29 | println('v: $v') +vlib/v/checker/tests/unknown_method_suggest_name.vv:30:15: error: expression does not return a value + 28 | println('p: $p') + 29 | println('v: $v') + 30 | println('z: $z') + | ^ + 31 | } diff --git a/vlib/v/checker/tests/unknown_struct_field_suggest_name.out b/vlib/v/checker/tests/unknown_struct_field_suggest_name.out index 8efbe047a..98347d6d9 100644 --- a/vlib/v/checker/tests/unknown_struct_field_suggest_name.out +++ b/vlib/v/checker/tests/unknown_struct_field_suggest_name.out @@ -6,3 +6,10 @@ Did you mean `xxxx`? | ~~~~ 12 | println('x: $x') 13 | } +vlib/v/checker/tests/unknown_struct_field_suggest_name.vv:12:19: error: expression does not return a value + 10 | println('p: $p') + 11 | for x in p.xxxa { + 12 | println('x: $x') + | ^ + 13 | } + 14 | } -- 2.39.5