diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 1702602e67..5a19f2a6b0 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -411,6 +411,9 @@ pub const ( error_type = new_type(error_type_idx) charptr_types = [charptr_type, new_type(char_type_idx).set_nr_muls(1)] byteptr_types = [byteptr_type, new_type(byte_type_idx).set_nr_muls(1)] + cptr_or_bptr_types = [charptr_type, byteptr_type, new_type(char_type_idx).set_nr_muls(1), + new_type(byte_type_idx).set_nr_muls(1), + ] ) pub const ( diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 47772a326b..23246c6f97 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -67,6 +67,7 @@ pub mut: inside_anon_fn bool inside_ref_lit bool inside_fn_arg bool // `a`, `b` in `a.f(b)` + inside_c_call bool // true inside C.printf( param ) calls, but NOT in nested calls, unless they are also C. skip_flags bool // should `#flag` and `#include` be skipped mut: files []ast.File @@ -90,7 +91,6 @@ mut: inside_println_arg bool inside_decl_rhs bool need_recheck_generic_fns bool // need recheck generic fns because there are cascaded nested generic fn - is_c_call bool // remove once C.c_call("string") deprecation is removed } pub fn new_checker(table &ast.Table, pref &pref.Preferences) &Checker { @@ -1694,6 +1694,11 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, call_exp } pub fn (mut c Checker) method_call(mut call_expr ast.CallExpr) ast.Type { + was_inside_c_call := c.inside_c_call + c.inside_c_call = call_expr.language == .c + defer { + c.inside_c_call = was_inside_c_call + } left_type := c.expr(call_expr.left) c.expected_type = left_type mut is_generic := left_type.has_flag(.generic) @@ -2176,10 +2181,10 @@ fn (mut c Checker) array_builtin_method_call(mut call_expr ast.CallExpr, left_ty } pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { - was_c_call := c.is_c_call - c.is_c_call = call_expr.language == .c + was_inside_c_call := c.inside_c_call + c.inside_c_call = call_expr.language == .c defer { - c.is_c_call = was_c_call + c.inside_c_call = was_inside_c_call } fn_name := call_expr.name if fn_name == 'main' { @@ -2506,6 +2511,10 @@ pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { c.warn('automatic referencing/dereferencing is deprecated and will be removed soon (got: $typ.nr_muls() references, expected: $param.typ.nr_muls() references)', call_arg.pos) } + if func.language == .c && typ == ast.string_type && param.typ in ast.cptr_or_bptr_types { + c.warn("automatic string to C-string conversion is deprecated and will be removed on 2021-06-19, use `c''` and set the C function parameter type to `&u8`", + call_arg.pos) + } } if func.generic_names.len != call_expr.concrete_types.len { // no type arguments given in call, attempt implicit instantiation @@ -4760,10 +4769,6 @@ pub fn (mut c Checker) expr(node ast.Expr) ast.Type { // string literal starts with "c": `C.printf(c'hello')` return ast.byte_type.set_nr_muls(1) } - if node.language != .c && c.is_c_call { - c.warn("automatic string to C-string conversion is deprecated and will be removed on 2021-06-19, use `c''` and set the C function parameter type to `&u8`", - node.pos) - } return ast.string_type } ast.StringInterLiteral {