From 436b19c408a2eed3b400eafd6889eacb6ab5ea32 Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Sun, 4 Sep 2022 16:45:26 +0530 Subject: [PATCH] checker: add error for mismatched types and format character for string interpolation (#15639) --- vlib/v/checker/str.v | 7 +++ .../tests/str_interpol_invalid_err.out | 55 +++++++++++++++++++ .../checker/tests/str_interpol_invalid_err.vv | 16 ++++++ 3 files changed, 78 insertions(+) create mode 100644 vlib/v/checker/tests/str_interpol_invalid_err.out create mode 100644 vlib/v/checker/tests/str_interpol_invalid_err.vv diff --git a/vlib/v/checker/str.v b/vlib/v/checker/str.v index 8eea09bca..de4cdc26b 100644 --- a/vlib/v/checker/str.v +++ b/vlib/v/checker/str.v @@ -94,6 +94,13 @@ pub fn (mut c Checker) string_inter_lit(mut node ast.StringInterLiteral) ast.Typ c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`', node.fmt_poss[i]) } + // v fmt doesn't format this correctly + if + c.table.final_sym(typ).kind in [.array, .array_fixed, .struct_, .interface_, .none_, .map, .sum_type] + && fmt in [`E`, `F`, `G`, `e`, `f`, `g`, `d`, `u`, `x`, `X`, `o`, `c`, `p`, `b`] { + c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`', + node.fmt_poss[i]) + } node.need_fmts[i] = fmt != c.get_default_fmt(ftyp, typ) } // check recursive str diff --git a/vlib/v/checker/tests/str_interpol_invalid_err.out b/vlib/v/checker/tests/str_interpol_invalid_err.out new file mode 100644 index 000000000..41c68f042 --- /dev/null +++ b/vlib/v/checker/tests/str_interpol_invalid_err.out @@ -0,0 +1,55 @@ +vlib/v/checker/tests/str_interpol_invalid_err.vv:8:13: error: illegal format specifier `x` for type `[]int` + 6 | + 7 | fn main() { + 8 | _ = '${[1]:x}' + | ^ + 9 | _ = '${[1]!:x}' + 10 | _ = '${Foo{}:x}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:9:14: error: illegal format specifier `x` for type `[1]int` + 7 | fn main() { + 8 | _ = '${[1]:x}' + 9 | _ = '${[1]!:x}' + | ^ + 10 | _ = '${Foo{}:x}' + 11 | _ = '${[1]:f}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:10:15: error: illegal format specifier `x` for type `Foo` + 8 | _ = '${[1]:x}' + 9 | _ = '${[1]!:x}' + 10 | _ = '${Foo{}:x}' + | ^ + 11 | _ = '${[1]:f}' + 12 | _ := '${none:F}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:11:13: error: illegal format specifier `f` for type `[]int` + 9 | _ = '${[1]!:x}' + 10 | _ = '${Foo{}:x}' + 11 | _ = '${[1]:f}' + | ^ + 12 | _ := '${none:F}' + 13 | _ = '${{"a": "b"}:x}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:12:15: error: illegal format specifier `F` for type `none` + 10 | _ = '${Foo{}:x}' + 11 | _ = '${[1]:f}' + 12 | _ := '${none:F}' + | ^ + 13 | _ = '${{"a": "b"}:x}' + 14 | _ = '${Alias(Foo{}):x}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:13:20: error: illegal format specifier `x` for type `map[string]string` + 11 | _ = '${[1]:f}' + 12 | _ := '${none:F}' + 13 | _ = '${{"a": "b"}:x}' + | ^ + 14 | _ = '${Alias(Foo{}):x}' + 15 | _ = '${SumType(int(5)):o}' +vlib/v/checker/tests/str_interpol_invalid_err.vv:14:22: error: illegal format specifier `x` for type `Alias` + 12 | _ := '${none:F}' + 13 | _ = '${{"a": "b"}:x}' + 14 | _ = '${Alias(Foo{}):x}' + | ^ + 15 | _ = '${SumType(int(5)):o}' + 16 | } +vlib/v/checker/tests/str_interpol_invalid_err.vv:15:25: error: illegal format specifier `o` for type `SumType` + 13 | _ = '${{"a": "b"}:x}' + 14 | _ = '${Alias(Foo{}):x}' + 15 | _ = '${SumType(int(5)):o}' + | ^ + 16 | } diff --git a/vlib/v/checker/tests/str_interpol_invalid_err.vv b/vlib/v/checker/tests/str_interpol_invalid_err.vv new file mode 100644 index 000000000..b938fcfc5 --- /dev/null +++ b/vlib/v/checker/tests/str_interpol_invalid_err.vv @@ -0,0 +1,16 @@ +struct Foo {} + +type Alias = Foo + +type SumType = Alias | int + +fn main() { + _ = '${[1]:x}' + _ = '${[1]!:x}' + _ = '${Foo{}:x}' + _ = '${[1]:f}' + _ := '${none:F}' + _ = '${{"a": "b"}:x}' + _ = '${Alias(Foo{}):x}' + _ = '${SumType(int(5)):o}' +} -- 2.30.2