From 4cef26619816a234e6c396e532e4c4ebcf1dbf31 Mon Sep 17 00:00:00 2001 From: Swastik Date: Thu, 2 Nov 2023 19:50:18 +0530 Subject: [PATCH 1/3] checker: warn on unused imported functions used via `import math { sin, cos }` --- vlib/v/checker/checker.v | 3 +++ .../checker/tests/import_sym_fn_unused_warning_err.out | 10 ++++++++++ .../checker/tests/import_sym_fn_unused_warning_err.vv | 3 +++ 3 files changed, 16 insertions(+) create mode 100644 vlib/v/checker/tests/import_sym_fn_unused_warning_err.out create mode 100644 vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 9da0900d9d9004..8ffadd8081ec29 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2717,6 +2717,9 @@ fn (mut c Checker) import_stmt(node ast.Import) { if !func.is_pub { c.error('module `${node.mod}` function `${sym.name}()` is private', sym.pos) } + if func.usages != 1 { + c.warn('module `${node.mod}` function `${sym.name}()` is unused', sym.pos) + } continue } if _ := c.file.global_scope.find_const(name) { diff --git a/vlib/v/checker/tests/import_sym_fn_unused_warning_err.out b/vlib/v/checker/tests/import_sym_fn_unused_warning_err.out new file mode 100644 index 00000000000000..d0bb2c363db71a --- /dev/null +++ b/vlib/v/checker/tests/import_sym_fn_unused_warning_err.out @@ -0,0 +1,10 @@ +vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv:1:15: warning: module `math` function `sin()` is unused + 1 | import math { sin, cos } + | ~~~ + 2 | + 3 | fn main() {} +vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv:1:20: warning: module `math` function `cos()` is unused + 1 | import math { sin, cos } + | ~~~ + 2 | + 3 | fn main() {} diff --git a/vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv b/vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv new file mode 100644 index 00000000000000..e5a7d32933c895 --- /dev/null +++ b/vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv @@ -0,0 +1,3 @@ +import math { sin, cos } + +fn main() {} From cd84f9da7bfca7e30d9436f274b120c44482e105 Mon Sep 17 00:00:00 2001 From: Swastik Date: Thu, 2 Nov 2023 19:50:42 +0530 Subject: [PATCH 2/3] Revert "checker: warn on unused imported functions used via `import math { sin, cos }`" This reverts commit ddf0468f1c4f9af54ada162712c212214e58ca56. --- vlib/v/checker/checker.v | 3 --- .../checker/tests/import_sym_fn_unused_warning_err.out | 10 ---------- .../checker/tests/import_sym_fn_unused_warning_err.vv | 3 --- 3 files changed, 16 deletions(-) delete mode 100644 vlib/v/checker/tests/import_sym_fn_unused_warning_err.out delete mode 100644 vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 8ffadd8081ec29..9da0900d9d9004 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2717,9 +2717,6 @@ fn (mut c Checker) import_stmt(node ast.Import) { if !func.is_pub { c.error('module `${node.mod}` function `${sym.name}()` is private', sym.pos) } - if func.usages != 1 { - c.warn('module `${node.mod}` function `${sym.name}()` is unused', sym.pos) - } continue } if _ := c.file.global_scope.find_const(name) { diff --git a/vlib/v/checker/tests/import_sym_fn_unused_warning_err.out b/vlib/v/checker/tests/import_sym_fn_unused_warning_err.out deleted file mode 100644 index d0bb2c363db71a..00000000000000 --- a/vlib/v/checker/tests/import_sym_fn_unused_warning_err.out +++ /dev/null @@ -1,10 +0,0 @@ -vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv:1:15: warning: module `math` function `sin()` is unused - 1 | import math { sin, cos } - | ~~~ - 2 | - 3 | fn main() {} -vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv:1:20: warning: module `math` function `cos()` is unused - 1 | import math { sin, cos } - | ~~~ - 2 | - 3 | fn main() {} diff --git a/vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv b/vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv deleted file mode 100644 index e5a7d32933c895..00000000000000 --- a/vlib/v/checker/tests/import_sym_fn_unused_warning_err.vv +++ /dev/null @@ -1,3 +0,0 @@ -import math { sin, cos } - -fn main() {} From 9cf189b7ed07fa1b6537c1502d0cb8a2f8fef19d Mon Sep 17 00:00:00 2001 From: Swastik Date: Sun, 24 Nov 2024 00:14:52 +0530 Subject: [PATCH 3/3] cgen: allow unwrapping of `x as string` expr --- vlib/v/gen/c/cgen.v | 33 +++++++++-------------- vlib/v/gen/c/utils.v | 26 +++++++++++++++++- vlib/v/tests/option_unwrap_as_cast_test.v | 23 ++++++++++++++++ 3 files changed, 60 insertions(+), 22 deletions(-) create mode 100644 vlib/v/tests/option_unwrap_as_cast_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 33e11919e1a6d9..bce15f34443a4d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4996,26 +4996,7 @@ fn (mut g Gen) ident(node ast.Ident) { g.write(name) } } else { - g.write('/*opt*/') - styp := g.base_type(node.info.typ) - if is_auto_heap { - g.write('(*(${styp}*)${name}->data)') - } else { - type_sym := g.table.sym(node.info.typ) - if type_sym.kind == .alias { - // Alias to Option type - parent_typ := (type_sym.info as ast.Alias).parent_type - if parent_typ.has_flag(.option) { - g.write('*((${g.base_type(parent_typ)}*)') - } - g.write('(*(${styp}*)${name}.data)') - if parent_typ.has_flag(.option) { - g.write('.data)') - } - } else { - g.write('(*(${styp}*)${name}.data)') - } - } + g.unwrap_option_type(node.info.typ, name, is_auto_heap) } if node.or_expr.kind != .absent && !(g.inside_opt_or_res && g.inside_assign && !g.is_assign_lhs) { @@ -7801,7 +7782,17 @@ fn (mut g Gen) as_cast(node ast.AsCast) { g.as_cast_type_names[idx] = variant_sym.name } } else { - g.expr(node.expr) + if node.expr is ast.Ident { + if node.expr.info is ast.IdentVar { + if node.expr.info.is_option { + g.unwrap_option_type(unwrapped_node_typ, node.expr.name, node.expr.is_auto_heap()) + } else { + g.expr(node.expr) + } + } + } else { + g.expr(node.expr) + } } } diff --git a/vlib/v/gen/c/utils.v b/vlib/v/gen/c/utils.v index bd88216c170ea0..57bc34866cdf50 100644 --- a/vlib/v/gen/c/utils.v +++ b/vlib/v/gen/c/utils.v @@ -32,7 +32,7 @@ fn (mut g Gen) unwrap_generic(typ ast.Type) ast.Type { } } } else if g.table.sym(typ).kind == .struct { - // resolve selector `a.foo` where `a` is struct[T] on non generic function + // resolve selector `a.foo` where `a` is struct[T] on non generic function sym := g.table.sym(typ) if sym.info is ast.Struct { if sym.info.generic_types.len > 0 { @@ -145,3 +145,27 @@ fn (mut g Gen) dot_or_ptr(val_type ast.Type) string { '.' } } + +@[inline] +fn (mut g Gen) unwrap_option_type(typ ast.Type, name string, is_auto_heap bool) { + g.write('/*opt*/') + styp := g.base_type(typ) + if is_auto_heap { + g.write('(*(${styp}*)${name}->data)') + } else { + type_sym := g.table.sym(typ) + if type_sym.kind == .alias { + // Alias to Option type + parent_typ := (type_sym.info as ast.Alias).parent_type + if parent_typ.has_flag(.option) { + g.write('*((${g.base_type(parent_typ)}*)') + } + g.write('(*(${styp}*)${name}.data)') + if parent_typ.has_flag(.option) { + g.write('.data)') + } + } else { + g.write('(*(${styp}*)${name}.data)') + } + } +} diff --git a/vlib/v/tests/option_unwrap_as_cast_test.v b/vlib/v/tests/option_unwrap_as_cast_test.v new file mode 100644 index 00000000000000..6bf6879a9f74d4 --- /dev/null +++ b/vlib/v/tests/option_unwrap_as_cast_test.v @@ -0,0 +1,23 @@ +fn get_opt(a int) ?string { + if a < 0 { + return none + } + return 'success' +} + +fn get_opt_int(a int) ?int { + if a < 0 { + return none + } + return 12 +} + +fn test_option_unwrap_as_cast() { + x := get_opt(1) + d := get_opt_int(12) + dump(d as int == 12) + dump('${x as string}' == 'success') + + assert d as int == 12 + assert x as string == 'success' +}