Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into fix_comptime_fn_det…
Browse files Browse the repository at this point in the history
…ection
  • Loading branch information
felipensp committed Jan 14, 2025
2 parents 5c88585 + 8f0242e commit 604764b
Show file tree
Hide file tree
Showing 18 changed files with 121 additions and 22 deletions.
2 changes: 1 addition & 1 deletion examples/gg/drag_n_drop.v
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const text_size = 16
struct App {
mut:
gg &gg.Context = unsafe { nil }
dropped_file_list []string = []string{}
dropped_file_list []string
}

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion vlib/builtin/builtin.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
module builtin

// isnil returns true if an object is nil (only for C objects).
@[inline]
@[inline; markused]
pub fn isnil(v voidptr) bool {
return v == 0
}
Expand Down
4 changes: 2 additions & 2 deletions vlib/net/ftp/ftp.v
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ mut:
// new returns an `FTP` instance.
pub fn new() FTP {
mut f := FTP{
conn: 0
conn: unsafe { nil }
}
f.buffer_size = 1024
return f
Expand Down Expand Up @@ -184,7 +184,7 @@ fn new_dtp(msg string) !&DTP {
mut dtp := &DTP{
ip: ip
port: port
conn: 0
conn: unsafe { nil }
}
conn := net.dial_tcp('${ip}:${port}') or { return error('Cannot connect to the data channel') }
dtp.conn = conn
Expand Down
1 change: 1 addition & 0 deletions vlib/os/file.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ pub fn (f &File) read_bytes_into(pos u64, mut buf []u8) !int {
return nbytes
} $else {
C.fseeko(f.cfile, pos, C.SEEK_SET)
// TODO(alex): require casts for voidptrs? &C.FILE(f.cfile)
nbytes := fread(buf.data, 1, buf.len, f.cfile)!
$if debug {
C.fseeko(f.cfile, 0, C.SEEK_SET)
Expand Down
2 changes: 1 addition & 1 deletion vlib/os/os.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ pub fn vfopen(path string, mode string) !&C.FILE {
} $else {
fp = C.fopen(&char(path.str), &char(mode.str))
}
if isnil(fp) {
if isnil(voidptr(fp)) {
return error_posix(msg: 'failed to open file "${path}"')
} else {
return fp
Expand Down
2 changes: 1 addition & 1 deletion vlib/time/time_windows.c.v
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ fn vpc_now() u64 {
fn local_as_unix_time() i64 {
t := C.time(0)
tm := C.localtime(&t)
return make_unix_time(tm)
return make_unix_time(*tm)
}

// local - return the time `t`, converted to the currently active local timezone
Expand Down
1 change: 1 addition & 0 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ pub mut:
is_minify bool
is_anon bool
is_generic bool
is_shared bool
has_option bool // contains any option field
generic_types []Type
concrete_types []Type
Expand Down
7 changes: 6 additions & 1 deletion vlib/v/checker/autocomplete.v
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import strings
import v.ast
import os

struct ACFieldMethod {
name string
typ string
}

fn (mut c Checker) ident_autocomplete(node ast.Ident) {
// Mini LS hack (v -line-info "a.v:16")
println(
Expand Down Expand Up @@ -81,7 +86,7 @@ fn (mut c Checker) ident_autocomplete(node ast.Ident) {
}
}

fn build_method_summary(method &ast.Fn) string {
fn build_method_summary(method ast.Fn) string {
mut s := method.name + '('
for i, param in method.params {
s += param.name
Expand Down
5 changes: 0 additions & 5 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -3904,11 +3904,6 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type {
return ast.string_type
}

struct ACFieldMethod {
name string
typ string
}

fn (mut c Checker) resolve_var_fn(func &ast.Fn, mut node ast.Ident, name string) ast.Type {
mut fn_type := ast.new_type(c.table.find_or_register_fn_type(func, false, true))
if func.generic_names.len > 0 {
Expand Down
25 changes: 20 additions & 5 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1754,11 +1754,26 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
call_arg.pos)
}
// Warn about automatic (de)referencing, which will be removed soon.
if func.language != .c && !c.inside_unsafe && arg_typ.nr_muls() != param.typ.nr_muls()
&& !(call_arg.is_mut && param.is_mut) && !(!call_arg.is_mut && !param.is_mut)
&& param.typ !in [ast.byteptr_type, ast.charptr_type, ast.voidptr_type, ast.nil_type] {
c.warn('automatic referencing/dereferencing is deprecated and will be removed soon (got: ${arg_typ.nr_muls()} references, expected: ${param.typ.nr_muls()} references)',
call_arg.pos)
if func.language != .c && !c.inside_unsafe && !(call_arg.is_mut && param.is_mut) {
if arg_typ.nr_muls() != param.typ.nr_muls()
&& param.typ !in [ast.byteptr_type, ast.charptr_type, ast.voidptr_type, ast.nil_type]
&& arg_typ != ast.voidptr_type && !(!call_arg.is_mut && !param.is_mut) //&& !(!call_arg.is_mut && !param.is_mut)
{
c.warn('automatic referencing/dereferencing is deprecated and will be removed soon (got: ${arg_typ.nr_muls()} references, expected: ${param.typ.nr_muls()} references)',
call_arg.pos)
}
// A special case of the check to not allow voidptr params like in the recently reported raylib
// bug with fn...
// fn f(p &Foo) => f(foo) -- do not allow this, force f(&foo)
// if !c.is_builtin_mod
else if param.typ == ast.voidptr_type && func.language == .v
&& arg_typ !in [ast.voidptr_type, ast.nil_type] && arg_typ.nr_muls() == 0
&& func.name !in ['isnil', 'ptr_str'] && !func.name.starts_with('json.')
&& arg_typ_sym.kind !in [.float_literal, .int_literal, .charptr]
&& !c.pref.backend.is_js() {
c.warn('automatic ${arg_typ_sym.name} referencing/dereferencing into voidptr is deprecated and will be removed soon; use `foo(&x)` instead of `foo(x)`',
call_arg.pos)
}
}
}
if func.generic_names.len != node.concrete_types.len {
Expand Down
7 changes: 7 additions & 0 deletions vlib/v/checker/tests/auto_ref_voidptr.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
vlib/v/checker/tests/auto_ref_voidptr.vv:9:9: warning: automatic Aa referencing/dereferencing into voidptr is deprecated and will be removed soon; use `foo(&x)` instead of `foo(x)`
7 | fn main() {
8 | a := Aa{}
9 | foo(3, a)
| ^
10 | // foo2(a)
11 | }
11 changes: 11 additions & 0 deletions vlib/v/checker/tests/auto_ref_voidptr.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
fn foo(x int, p voidptr) {}

fn foo2(p &Aa) {}

struct Aa {}

fn main() {
a := Aa{}
foo(3, a)
// foo2(a)
}
3 changes: 3 additions & 0 deletions vlib/v/fmt/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,9 @@ fn (mut f Fmt) write_anon_struct_field_decl(field_typ ast.Type, field_anon_decl
info := sym.info as ast.Struct
if info.is_anon {
f.indent++
if info.is_shared {
f.write('shared ')
}
f.struct_decl(field_anon_decl, true)
f.indent--
return true
Expand Down
8 changes: 6 additions & 2 deletions vlib/v/gen/c/auto_str_methods.v
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,11 @@ fn (mut g Gen) gen_str_for_struct(info ast.Struct, lang ast.Language, styp strin
} else {
''
}
base_fmt := g.type_to_fmt(g.unwrap_generic(field.typ))
mut base_typ := g.unwrap_generic(field.typ)
if base_typ.has_flag(.shared_f) {
base_typ = base_typ.clear_flag(.shared_f).deref()
}
base_fmt := g.type_to_fmt(base_typ)
is_opt_field := field.typ.has_flag(.option)

// manage prefix and quote symbol for the filed
Expand Down Expand Up @@ -1194,7 +1198,7 @@ fn struct_auto_str_func(sym &ast.TypeSymbol, lang ast.Language, _field_type ast.
if !field_type.is_ptr() && field_type.has_option_or_result() {
method_str = '(*(${sym.name}*)it${op}${final_field_name}.data)'
} else {
method_str = 'it${op}${final_field_name}'
method_str = 'it${op}${final_field_name}${sufix}'
}
if sym.kind == .bool {
return '${method_str} ? _SLIT("true") : _SLIT("false")', false
Expand Down
21 changes: 20 additions & 1 deletion vlib/v/gen/c/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,14 @@ fn (mut g Gen) get_embed_field_name(field_type ast.Type, field_name string) stri
return s
}

fn (mut g Gen) init_shared_field(field ast.StructField) {
field_typ := field.typ.deref()
shared_styp := g.styp(field_typ)
g.write('(${shared_styp}*)__dup${shared_styp}(&(${shared_styp}){.mtx= {0}, .val=')
g.write(g.type_default(field_typ.clear_flag(.shared_f)))
g.write('}, sizeof(${shared_styp}))')
}

fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
old_inside_cast_in_heap := g.inside_cast_in_heap
g.inside_cast_in_heap = 0
Expand All @@ -428,6 +436,11 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
return false
} else if !field.has_default_expr {
mut has_option_field := false
if sym.info.is_shared || field.typ.has_flag(.shared_f) {
g.write('.${field_name} = ')
g.init_shared_field(field)
return true
}
for fd in sym.info.fields {
if fd.typ.has_flag(.option) {
has_option_field = true
Expand Down Expand Up @@ -520,6 +533,8 @@ fn (mut g Gen) zero_struct_field(field ast.StructField) bool {
}
}
g.write('}')
} else if field.typ.has_flag(.shared_f) {
g.init_shared_field(field)
} else {
g.write(g.type_default(field.typ))
}
Expand Down Expand Up @@ -570,7 +585,11 @@ fn (mut g Gen) struct_decl(s ast.Struct, name string, is_anon bool) {
}
}
if is_anon {
g.type_definitions.write_string('\t${name} ')
if s.is_shared {
g.type_definitions.write_string('\t__shared__${name}* ')
} else {
g.type_definitions.write_string('\t${name} ')
}
return
} else if s.is_union {
if g.is_cc_msvc && aligned_attr != '' {
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/parser/parser.v
Original file line number Diff line number Diff line change
Expand Up @@ -2597,7 +2597,7 @@ fn (p &Parser) is_generic_call() bool {
const valid_tokens_inside_types = [token.Kind.lsbr, .rsbr, .name, .dot, .comma, .key_fn, .lt]

fn (mut p Parser) is_generic_cast() bool {
if !ast.type_can_start_with_token(p.tok) {
if !ast.type_can_start_with_token(&p.tok) {
return false
}
mut i := 0
Expand Down
14 changes: 13 additions & 1 deletion vlib/v/parser/struct.v
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
attrs := p.attrs
start_pos := p.tok.pos()
mut is_pub := p.tok.kind == .key_pub
mut is_shared := p.tok.kind == .key_shared
if is_pub {
p.next()
}
if is_anon {
if is_shared {
p.register_auto_import('sync')
p.next()
}
is_pub = true
}
is_union := p.tok.kind == .key_union
Expand Down Expand Up @@ -236,12 +241,18 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
// struct field
field_name = p.check_name()
p.inside_struct_field_decl = true
if p.tok.kind == .key_struct {
if p.tok.kind == .key_struct
|| (p.tok.kind == .key_shared && p.peek_tok.kind == .key_struct) {
// Anon structs
field_is_shared := p.tok.kind == .key_shared
p.anon_struct_decl = p.struct_decl(true)
p.anon_struct_decl.language = language
// Find the registered anon struct type, it was registered above in `p.struct_decl()`
typ = p.table.find_type_idx(p.anon_struct_decl.name)
if field_is_shared {
typ = typ.set_flag(.shared_f)
typ = typ.set_nr_muls(1)
}
} else {
start_type_pos := p.tok.pos()
typ = p.parse_type()
Expand Down Expand Up @@ -379,6 +390,7 @@ fn (mut p Parser) struct_decl(is_anon bool) ast.StructDecl {
generic_types: generic_types
attrs: attrs
is_anon: is_anon
is_shared: is_shared
has_option: has_option
}
is_pub: is_pub
Expand Down
26 changes: 26 additions & 0 deletions vlib/v/tests/structs/struct_field_shared_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
struct Foo {
bar shared struct {
mut:
foo int
bar int
}
baz shared int
}

fn test_main() {
assert Foo{}.str() == 'Foo{
bar: struct {
foo: 0
bar: 0
}
baz: 0
}'
mut t := Foo{}
lock t.bar {
t.bar.foo = 1
t.bar.bar = 2
}
rlock t.bar {
assert t.bar.foo + t.bar.bar == 3
}
}

0 comments on commit 604764b

Please sign in to comment.