diff options
| -rw-r--r-- | core/os/dir.odin | 4 | ||||
| -rw-r--r-- | core/os/dir_posix_darwin.odin | 2 | ||||
| -rw-r--r-- | core/os/path.odin | 4 | ||||
| -rw-r--r-- | core/os/path_js.odin | 4 | ||||
| -rw-r--r-- | core/os/path_linux.odin | 10 | ||||
| -rw-r--r-- | core/os/path_posix.odin | 8 | ||||
| -rw-r--r-- | core/os/path_wasi.odin | 6 | ||||
| -rw-r--r-- | core/os/path_windows.odin | 4 | ||||
| -rw-r--r-- | core/os/temp_file.odin | 2 | ||||
| -rw-r--r-- | src/check_expr.cpp | 119 |
10 files changed, 130 insertions, 33 deletions
diff --git a/core/os/dir.odin b/core/os/dir.odin index 2548480c2..02dcb87af 100644 --- a/core/os/dir.odin +++ b/core/os/dir.odin @@ -208,7 +208,7 @@ read_directory_iterator :: proc(it: ^Read_Directory_Iterator) -> (fi: File_Info, } // Recursively copies a directory to `dst` from `src` -copy_directory_all :: proc(dst, src: string, dst_perm := 0o755) -> Error { +copy_directory_all :: proc(dst, src: string, dst_perm := Permissions_Default) -> Error { when #defined(_copy_directory_all_native) { return _copy_directory_all_native(dst, src, dst_perm) } else { @@ -217,7 +217,7 @@ copy_directory_all :: proc(dst, src: string, dst_perm := 0o755) -> Error { } @(private) -_copy_directory_all :: proc(dst, src: string, dst_perm := 0o755) -> Error { +_copy_directory_all :: proc(dst, src: string, dst_perm := Permissions_Default) -> Error { err := make_directory(dst, dst_perm) if err != nil && err != .Exist { return err diff --git a/core/os/dir_posix_darwin.odin b/core/os/dir_posix_darwin.odin index e67c917b4..ddd25c1fc 100644 --- a/core/os/dir_posix_darwin.odin +++ b/core/os/dir_posix_darwin.odin @@ -3,7 +3,7 @@ package os import "core:sys/darwin" -_copy_directory_all_native :: proc(dst, src: string, dst_perm := 0o755) -> (err: Error) { +_copy_directory_all_native :: proc(dst, src: string, dst_perm := Permissions_Default) -> (err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) csrc := clone_to_cstring(src, temp_allocator) or_return diff --git a/core/os/path.odin b/core/os/path.odin index 7ee95c1c2..766adcaa9 100644 --- a/core/os/path.odin +++ b/core/os/path.odin @@ -74,7 +74,7 @@ Make a new directory. If `path` is relative, it will be relative to the process's current working directory. */ -make_directory :: proc(name: string, perm: int = 0o755) -> Error { +make_directory :: proc(name: string, perm := Permissions_Default_Directory) -> Error { return _mkdir(name, perm) } @@ -85,7 +85,7 @@ Make a new directory, creating new intervening directories when needed. If `path` is relative, it will be relative to the process's current working directory. */ -make_directory_all :: proc(path: string, perm: int = 0o755) -> Error { +make_directory_all :: proc(path: string, perm := Permissions_Default_Directory) -> Error { return _mkdir_all(path, perm) } diff --git a/core/os/path_js.odin b/core/os/path_js.odin index 874b45c89..556d93b16 100644 --- a/core/os/path_js.odin +++ b/core/os/path_js.odin @@ -16,11 +16,11 @@ _is_path_separator :: proc(c: byte) -> (ok: bool) { return c == _Path_Separator } -_mkdir :: proc(name: string, perm: int) -> (err: Error) { +_mkdir :: proc(name: string, perm: Permissions) -> (err: Error) { return .Unsupported } -_mkdir_all :: proc(path: string, perm: int) -> (err: Error) { +_mkdir_all :: proc(path: string, perm: Permissions) -> (err: Error) { return .Unsupported } diff --git a/core/os/path_linux.odin b/core/os/path_linux.odin index ca68fffb1..cba4b4e98 100644 --- a/core/os/path_linux.odin +++ b/core/os/path_linux.odin @@ -17,14 +17,14 @@ _is_path_separator :: proc(c: byte) -> bool { return c == _Path_Separator } -_mkdir :: proc(path: string, perm: int) -> Error { +_mkdir :: proc(path: string, perm: Permissions) -> Error { temp_allocator := TEMP_ALLOCATOR_GUARD({}) path_cstr := clone_to_cstring(path, temp_allocator) or_return - return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)u32(perm))) + return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)transmute(u32)perm)) } -_mkdir_all :: proc(path: string, perm: int) -> Error { - mkdirat :: proc(dfd: linux.Fd, path: []u8, perm: int, has_created: ^bool) -> Error { +_mkdir_all :: proc(path: string, perm: Permissions) -> Error { + mkdirat :: proc(dfd: linux.Fd, path: []u8, perm: Permissions, has_created: ^bool) -> Error { i: int for ; i < len(path) - 1 && path[i] != '/'; i += 1 {} if i == 0 { @@ -34,7 +34,7 @@ _mkdir_all :: proc(path: string, perm: int) -> Error { new_dfd, errno := linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS) #partial switch errno { case .ENOENT: - if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)u32(perm)); errno != .NONE { + if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)transmute(u32)perm); errno != .NONE { return _get_platform_error(errno) } has_created^ = true diff --git a/core/os/path_posix.odin b/core/os/path_posix.odin index a877af3e6..6f383903a 100644 --- a/core/os/path_posix.odin +++ b/core/os/path_posix.odin @@ -14,16 +14,16 @@ _is_path_separator :: proc(c: byte) -> bool { return c == _Path_Separator } -_mkdir :: proc(name: string, perm: int) -> (err: Error) { +_mkdir :: proc(name: string, perm: Permissions) -> (err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) cname := clone_to_cstring(name, temp_allocator) or_return - if posix.mkdir(cname, transmute(posix.mode_t)posix._mode_t(perm)) != .OK { + if posix.mkdir(cname, transmute(posix.mode_t)posix._mode_t(transmute(u32)perm)) != .OK { return _get_platform_error() } return nil } -_mkdir_all :: proc(path: string, perm: int) -> Error { +_mkdir_all :: proc(path: string, perm: Permissions) -> Error { if path == "" { return .Invalid_Path } @@ -37,7 +37,7 @@ _mkdir_all :: proc(path: string, perm: int) -> Error { clean_path := clean_path(path, temp_allocator) or_return return internal_mkdir_all(clean_path, perm) - internal_mkdir_all :: proc(path: string, perm: int) -> Error { + internal_mkdir_all :: proc(path: string, perm: Permissions) -> Error { dir, file := split_path(path) if file != path && dir != "/" { if len(dir) > 1 && dir[len(dir) - 1] == '/' { diff --git a/core/os/path_wasi.odin b/core/os/path_wasi.odin index aa7740497..e7c003001 100644 --- a/core/os/path_wasi.odin +++ b/core/os/path_wasi.odin @@ -14,7 +14,7 @@ _is_path_separator :: proc(c: byte) -> bool { return c == _Path_Separator } -_mkdir :: proc(name: string, perm: int) -> Error { +_mkdir :: proc(name: string, perm: Permissions) -> Error { dir_fd, relative, ok := match_preopen(name) if !ok { return .Invalid_Path @@ -23,7 +23,7 @@ _mkdir :: proc(name: string, perm: int) -> Error { return _get_platform_error(wasi.path_create_directory(dir_fd, relative)) } -_mkdir_all :: proc(path: string, perm: int) -> Error { +_mkdir_all :: proc(path: string, perm: Permissions) -> Error { if path == "" { return .Invalid_Path } @@ -46,7 +46,7 @@ _mkdir_all :: proc(path: string, perm: int) -> Error { internal_mkdir_all(dir) or_return } - err := _mkdir(path, 0) + err := _mkdir(path, Permissions_Default) if err == .Exist { err = nil } return err } diff --git a/core/os/path_windows.odin b/core/os/path_windows.odin index 6ccab1dab..1a0245c52 100644 --- a/core/os/path_windows.odin +++ b/core/os/path_windows.odin @@ -13,7 +13,7 @@ _is_path_separator :: proc(c: byte) -> bool { return c == '\\' || c == '/' } -_mkdir :: proc(name: string, perm: int) -> Error { +_mkdir :: proc(name: string, perm: Permissions) -> Error { temp_allocator := TEMP_ALLOCATOR_GUARD({}) if !win32.CreateDirectoryW(_fix_long_path(name, temp_allocator) or_return, nil) { return _get_platform_error() @@ -21,7 +21,7 @@ _mkdir :: proc(name: string, perm: int) -> Error { return nil } -_mkdir_all :: proc(path: string, perm: int) -> Error { +_mkdir_all :: proc(path: string, perm: Permissions) -> Error { fix_root_directory :: proc(p: string) -> (s: string, allocated: bool, err: runtime.Allocator_Error) { if len(p) == len(`\\?\c:`) { if is_path_separator(p[0]) && is_path_separator(p[1]) && p[2] == '?' && is_path_separator(p[3]) && p[5] == ':' { diff --git a/core/os/temp_file.odin b/core/os/temp_file.odin index be10eb22e..9068b6590 100644 --- a/core/os/temp_file.odin +++ b/core/os/temp_file.odin @@ -58,7 +58,7 @@ make_directory_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) attempts := 0 for { name := concatenate_strings_from_buffer(name_buf[:], prefix, random_string(rand_buf[:]), suffix) - err = make_directory(name, 0o700) + err = make_directory(name) if err == nil { return clone_string(name, allocator) } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index f2cdcc2ea..14967482f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -7255,18 +7255,45 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } } + // auto print_argument_types = [&]() { + // error_line("\tGiven argument types: ("); + // isize i = 0; + // for (Operand const &o : positional_operands) { + // if (i++ > 0) error_line(", "); + // gbString type = type_to_string(o.type); + // defer (gb_string_free(type)); + // error_line("%s", type); + // } + // for (Operand const &o : named_operands) { + // if (i++ > 0) error_line(", "); + + // gbString type = type_to_string(o.type); + // defer (gb_string_free(type)); + + // if (i < ce->split_args->named.count) { + // Ast *named_field = ce->split_args->named[i]; + // ast_node(fv, FieldValue, named_field); + + // gbString field = expr_to_string(fv->field); + // defer (gb_string_free(field)); + + // error_line("%s = %s", field, type); + // } else { + // error_line("%s", type); + // } + // } + // error_line(")\n"); + // }; + auto print_argument_types = [&]() { - error_line("\tGiven argument types: ("); + error_line("\tGiven argument types:\n"); isize i = 0; for (Operand const &o : positional_operands) { - if (i++ > 0) error_line(", "); gbString type = type_to_string(o.type); defer (gb_string_free(type)); - error_line("%s", type); + error_line("\t • %s\n", type); } for (Operand const &o : named_operands) { - if (i++ > 0) error_line(", "); - gbString type = type_to_string(o.type); defer (gb_string_free(type)); @@ -7277,12 +7304,11 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, gbString field = expr_to_string(fv->field); defer (gb_string_free(field)); - error_line("%s = %s", field, type); + error_line("\t • %s = %s\n", field, type); } else { - error_line("%s", type); + error_line("\t • %s\n", type); } } - error_line(")\n"); }; if (valids.count == 0) { @@ -7298,9 +7324,6 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, if (procs.count == 0) { procs = proc_group_entities_cloned(c, *operand); } - if (procs.count > 0) { - error_line("Did you mean to use one of the following:\n"); - } // Try to reduce the list further for `$T: typeid` like parameters bool *possibly_ignore = temporary_alloc_array<bool>(procs.count); @@ -7397,6 +7420,80 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } spaces[max_spaces] = 0; + { + bool try_addr = false; + isize try_addr_idx = -1; + + for_array(i, procs) { + if (possibly_ignore_set != 0 && possibly_ignore[i]) { + continue; + } + Entity *proc = procs[i]; + TokenPos pos = proc->token.pos; + Type *t = base_type(proc->type); + if (t == t_invalid) continue; + GB_ASSERT(t->kind == Type_Proc); + if (t->Proc.params && t->Proc.params->Tuple.variables.count > 0) { + isize n = gb_min(t->Proc.params->Tuple.variables.count, positional_operands.count); + for (isize i = 0; i < n; i++) { + Type *dst = t->Proc.params->Tuple.variables[i]->type; + Operand src = positional_operands[i]; + if (check_is_assignable_to(c, &src, dst)) { + // okay + } else if (check_is_assignable_to(c, &src, type_deref(dst))) { + try_addr = true; + if (try_addr_idx < 0) { + try_addr_idx = i; + } + } + } + } + } + + if (try_addr) { + error_line(" \n"); + error_line("\tSuggestion:\n"); + error_line("\t\t%s(", expr_name); + isize i = 0; + for (Operand const &o : positional_operands) { + if (i++ > 0) error_line(", "); + gbString expr = expr_to_string(o.expr); + defer (gb_string_free(expr)); + + if (i-1 == try_addr_idx) { + error_line("&"); + } + error_line("%s", expr); + } + for (Operand const &o : named_operands) { + if (i++ > 0) error_line(", "); + + gbString expr = expr_to_string(o.expr); + defer (gb_string_free(expr)); + + if (i < ce->split_args->named.count) { + Ast *named_field = ce->split_args->named[i]; + ast_node(fv, FieldValue, named_field); + + gbString field = expr_to_string(fv->field); + defer (gb_string_free(field)); + + error_line("%s = %s", field, expr); + } else { + error_line("%s", expr); + } + } + error_line(")\n"); + + error_line(" \n"); // extra spaces to prevent newlines being consumed by the error handling syste, + } + } + + + if (procs.count > 0) { + error_line("Did you mean one of the following overloads?\n"); + } + for_array(i, procs) { if (possibly_ignore_set != 0 && possibly_ignore[i]) { continue; |