diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index 834f5bde69..fbbf1f552a 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -563,15 +563,15 @@ fn (a array) slice(start int, _end int) array { end := if _end == max_int { a.len } else { _end } // max_int $if !no_bounds_checking { if start > end { - panic('array.slice: invalid slice index (start>end):' + i64(start).str() + ', ' + - i64(end).str()) + panic('array.slice: invalid slice index (start>end):' + impl_i64_to_string(i64(start)) + + ', ' + impl_i64_to_string(end)) } if end > a.len { - panic('array.slice: slice bounds out of range (' + i64(end).str() + ' >= ' + - i64(a.len).str() + ')') + panic('array.slice: slice bounds out of range (' + impl_i64_to_string(end) + ' >= ' + + impl_i64_to_string(a.len) + ')') } if start < 0 { - panic('array.slice: slice bounds out of range (start<0):' + start.str()) + panic('array.slice: slice bounds out of range (start<0):' + impl_i64_to_string(start)) } } // TODO: integrate reference counting diff --git a/vlib/builtin/builtin.c.v b/vlib/builtin/builtin.c.v index 41e594cafd..3910cebfdd 100644 --- a/vlib/builtin/builtin.c.v +++ b/vlib/builtin/builtin.c.v @@ -184,19 +184,20 @@ pub fn c_error_number_str(errnum int) string { // panic_n prints an error message, followed by the given number, then exits the process with exit code of 1. @[noreturn] pub fn panic_n(s string, number1 i64) { - panic(s + number1.str()) + panic(s + impl_i64_to_string(number1)) } // panic_n2 prints an error message, followed by the given numbers, then exits the process with exit code of 1. @[noreturn] pub fn panic_n2(s string, number1 i64, number2 i64) { - panic(s + number1.str() + ', ' + number2.str()) + panic(s + impl_i64_to_string(number1) + ', ' + impl_i64_to_string(number2)) } // panic_n3 prints an error message, followed by the given numbers, then exits the process with exit code of 1. @[noreturn] fn panic_n3(s string, number1 i64, number2 i64, number3 i64) { - panic(s + number1.str() + ', ' + number2.str() + ', ' + number2.str()) + panic(s + impl_i64_to_string(number1) + ', ' + impl_i64_to_string(number2) + ', ' + + impl_i64_to_string(number2)) } // panic with a C-API error message matching `errnum` diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index cb769d6dbc..81887dcb62 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -11,7 +11,7 @@ pub type byte = u8 // ptr_str returns a string with the address of `ptr`. pub fn ptr_str(ptr voidptr) string { - buf1 := u64(ptr).hex() + buf1 := u64_to_hex_no_leading_zeros(u64(ptr), 16) return buf1 } @@ -182,13 +182,18 @@ pub fn (nn u32) str() string { // str returns the value of the `int_literal` as a `string`. @[inline] pub fn (n int_literal) str() string { - return i64(n).str() + return impl_i64_to_string(n) } // str returns the value of the `i64` as a `string`. // Example: assert i64(-200000).str() == '-200000' -@[direct_array_access; inline] +@[inline] pub fn (nn i64) str() string { + return impl_i64_to_string(nn) +} + +@[direct_array_access] +fn impl_i64_to_string(nn i64) string { unsafe { mut n := nn mut d := i64(0) diff --git a/vlib/builtin/string.v b/vlib/builtin/string.v index 54be8d021d..6a86b5f592 100644 --- a/vlib/builtin/string.v +++ b/vlib/builtin/string.v @@ -1168,8 +1168,8 @@ pub fn (s string) substr(start int, _end int) string { end := if _end == max_int { s.len } else { _end } // max_int $if !no_bounds_checking { if start > end || start > s.len || end > s.len || start < 0 || end < 0 { - panic('substr(' + start.str() + ', ' + end.str() + ') out of bounds (len=' + - s.len.str() + ') s=' + s) + panic('substr(' + impl_i64_to_string(start) + ', ' + impl_i64_to_string(end) + + ') out of bounds (len=' + impl_i64_to_string(s.len) + ') s=' + s) } } len := end - start @@ -1207,8 +1207,8 @@ pub fn (s string) substr_unsafe(start int, _end int) string { pub fn (s string) substr_with_check(start int, _end int) !string { end := if _end == max_int { s.len } else { _end } // max_int if start > end || start > s.len || end > s.len || start < 0 || end < 0 { - return error('substr(' + start.str() + ', ' + end.str() + ') out of bounds (len=' + - s.len.str() + ')') + return error('substr(' + impl_i64_to_string(start) + ', ' + impl_i64_to_string(end) + + ') out of bounds (len=' + impl_i64_to_string(s.len) + ')') } len := end - start if len == s.len { diff --git a/vlib/v/markused/markused.v b/vlib/v/markused/markused.v index 7cb0252b17..2169b7ee02 100644 --- a/vlib/v/markused/markused.v +++ b/vlib/v/markused/markused.v @@ -311,7 +311,6 @@ pub fn mark_used(mut table ast.Table, mut pref_ pref.Preferences, ast_files []&a mut walker := Walker.new( table: table - files: ast_files all_fns: all_fns all_consts: all_consts all_globals: all_globals diff --git a/vlib/v/markused/walker.v b/vlib/v/markused/walker.v index 38d169f2e2..3d21be8b0f 100644 --- a/vlib/v/markused/walker.v +++ b/vlib/v/markused/walker.v @@ -23,7 +23,6 @@ pub mut: used_panic int // option/result propagation pref &pref.Preferences = unsafe { nil } mut: - files []&ast.File all_fns map[string]ast.FnDecl all_consts map[string]ast.ConstField all_globals map[string]ast.GlobalField @@ -55,8 +54,8 @@ mut: uses_interp bool // string interpolation uses_guard bool uses_orm bool - uses_str bool // has .str() call - uses_free bool // has .free() call + uses_str map[ast.Type]bool // has .str() calls, and for which types + uses_free map[ast.Type]bool // has .free() calls, and for which types uses_spawn bool uses_dump bool uses_memdup bool // sumtype cast and &Struct{} @@ -107,9 +106,6 @@ pub fn (mut w Walker) mark_const_as_used(ckey string) { return } w.used_consts[ckey] = true - if ckey == 'c' { - println(ckey) - } cfield := w.all_consts[ckey] or { return } w.expr(cfield.expr) w.mark_by_type(cfield.typ) @@ -428,10 +424,13 @@ fn (mut w Walker) expr(node_ ast.Expr) { if sym.info is ast.Map { w.mark_by_type(w.table.find_or_register_array(sym.info.key_type)) } - } else if !w.uses_str && node.is_method && node.name == 'str' { - w.uses_str = true - } else if !w.uses_free && node.is_method && node.name == 'free' { - w.uses_free = true + } else if !node.is_method && node.args.len == 1 && node.args[0].typ != ast.string_type + && node.name in ['println', 'print', 'eprint', 'eprintln'] { + w.uses_str[node.args[0].typ] = true + } else if node.is_method && node.name == 'str' { + w.uses_str[node.left_type] = true + } else if node.is_method && node.name == 'free' { + w.uses_free[node.left_type] = true } if !w.is_builtin_mod && !w.uses_external_type { if node.is_method { @@ -1295,18 +1294,27 @@ fn (mut w Walker) mark_resource_dependencies() { if w.uses_arr_void { w.mark_by_type(w.table.find_or_register_array(ast.voidptr_type)) } + for typ, _ in w.table.used_features.print_types { + w.mark_by_type(typ) + } if w.trace_enabled { types := w.table.used_features.print_types.keys().map(w.table.type_to_str(it)) eprintln('>>>>>>>>>> PRINT TYPES ${types}') } - for typ, _ in w.table.used_features.print_types { - w.mark_by_type(typ) + if w.trace_enabled { + types := w.uses_str.keys().map(w.table.type_to_str(it)) + eprintln('>>>>>>>>>> USES .str() CALLS ON TYPES ${types}') + } + if w.trace_enabled { + types := w.uses_free.keys().map(w.table.type_to_str(it)) + eprintln('>>>>>>>>>> USES .free() CALLS ON TYPES ${types}') } if w.trace_enabled { eprintln('>>>>>>>>>> ALL_FNS LOOP') } mut has_ptr_print := false - has_str_call := w.uses_interp || w.uses_asserts || w.uses_str || w.features.print_types.len > 0 + has_str_call := w.uses_interp || w.uses_asserts || w.uses_str.len > 0 + || w.features.print_types.len > 0 for k, mut func in w.all_fns { if has_str_call && k.ends_with('.str') { if func.receiver.typ.idx() in w.used_syms { @@ -1318,7 +1326,7 @@ fn (mut w Walker) mark_resource_dependencies() { } continue } - if w.pref.autofree || (w.uses_free && k.ends_with('.free') + if w.pref.autofree || (w.uses_free.len > 0 && k.ends_with('.free') && func.receiver.typ.idx() in w.used_syms) { w.fn_by_name(k) continue