checker: no longer allow automatic dereferncing in `a = b`
parent
d1e9aa49ea
commit
ab3adf3346
|
@ -131,7 +131,7 @@ fn break_if_debugger_attached() {
|
||||||
unsafe {
|
unsafe {
|
||||||
mut ptr := &voidptr(0)
|
mut ptr := &voidptr(0)
|
||||||
*ptr = voidptr(0)
|
*ptr = voidptr(0)
|
||||||
_ = ptr
|
//_ = ptr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ pub fn get_clipboard_string() &char {
|
||||||
// special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
|
// special run-function for SOKOL_NO_ENTRY (in standard mode this is an empty stub)
|
||||||
[inline]
|
[inline]
|
||||||
pub fn run(desc &C.sapp_desc) {
|
pub fn run(desc &C.sapp_desc) {
|
||||||
g_desc = desc
|
g_desc = *desc
|
||||||
C.sapp_run(desc)
|
C.sapp_run(desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,8 @@ pub mut:
|
||||||
typ Type
|
typ Type
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (f Fn) new_method_with_receiver_type(new_type Type) Fn {
|
pub fn (f &Fn) new_method_with_receiver_type(new_type Type) Fn {
|
||||||
|
unsafe {
|
||||||
mut new_method := f
|
mut new_method := f
|
||||||
new_method.params = f.params.clone()
|
new_method.params = f.params.clone()
|
||||||
for i in 1 .. new_method.params.len {
|
for i in 1 .. new_method.params.len {
|
||||||
|
@ -131,10 +132,13 @@ pub fn (f Fn) new_method_with_receiver_type(new_type Type) Fn {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_method.params[0].typ = new_type
|
new_method.params[0].typ = new_type
|
||||||
return new_method
|
|
||||||
|
return *new_method
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (f FnDecl) new_method_with_receiver_type(new_type Type) FnDecl {
|
pub fn (f &FnDecl) new_method_with_receiver_type(new_type Type) FnDecl {
|
||||||
|
unsafe {
|
||||||
mut new_method := f
|
mut new_method := f
|
||||||
new_method.params = f.params.clone()
|
new_method.params = f.params.clone()
|
||||||
for i in 1 .. new_method.params.len {
|
for i in 1 .. new_method.params.len {
|
||||||
|
@ -143,7 +147,8 @@ pub fn (f FnDecl) new_method_with_receiver_type(new_type Type) FnDecl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_method.params[0].typ = new_type
|
new_method.params[0].typ = new_type
|
||||||
return new_method
|
return *new_method
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (p &Param) equals(o &Param) bool {
|
fn (p &Param) equals(o &Param) bool {
|
||||||
|
|
|
@ -246,6 +246,11 @@ pub fn (t Type) str() string {
|
||||||
return 'ast.Type(0x$t.hex() = ${u32(t)})'
|
return 'ast.Type(0x$t.hex() = ${u32(t)})'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (t &Table) type_str(typ Type) string {
|
||||||
|
sym := t.get_type_symbol(typ)
|
||||||
|
return sym.name
|
||||||
|
}
|
||||||
|
|
||||||
// debug returns a verbose representation of the information in the type `t`, useful for tracing/debugging
|
// debug returns a verbose representation of the information in the type `t`, useful for tracing/debugging
|
||||||
pub fn (t Type) debug() []string {
|
pub fn (t Type) debug() []string {
|
||||||
mut res := []string{}
|
mut res := []string{}
|
||||||
|
@ -309,6 +314,11 @@ pub fn (typ Type) is_pointer() bool {
|
||||||
return typ.idx() in ast.pointer_type_idxs
|
return typ.idx() in ast.pointer_type_idxs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[inline]
|
||||||
|
pub fn (typ Type) is_real_pointer() bool {
|
||||||
|
return typ.is_ptr() || typ.is_pointer()
|
||||||
|
}
|
||||||
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (typ Type) is_float() bool {
|
pub fn (typ Type) is_float() bool {
|
||||||
return typ.clear_flags() in ast.float_type_idxs
|
return typ.clear_flags() in ast.float_type_idxs
|
||||||
|
|
|
@ -288,7 +288,7 @@ pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
|
||||||
}
|
}
|
||||||
// allow direct int-literal assignment for pointers for now
|
// allow direct int-literal assignment for pointers for now
|
||||||
// maybe in the future optionals should be used for that
|
// maybe in the future optionals should be used for that
|
||||||
if expected.is_ptr() || expected.is_pointer() {
|
if expected.is_real_pointer() {
|
||||||
if got == ast.int_literal_type {
|
if got == ast.int_literal_type {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -4020,6 +4020,14 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Do not allow `a := 0; b := 0; a = &b`
|
||||||
|
if !is_decl && left is ast.Ident && !is_blank_ident && !left_type.is_real_pointer()
|
||||||
|
&& right_type.is_real_pointer() {
|
||||||
|
c.warn(
|
||||||
|
'cannot assign a reference to a value (this will be an error soon) left=${c.table.type_str(left_type)} $left_type.is_ptr() ' +
|
||||||
|
'right=${c.table.type_str(right_type)} $right_type.is_real_pointer() ptr=$right_type.is_ptr()',
|
||||||
|
node.pos)
|
||||||
|
}
|
||||||
node.left_types << left_type
|
node.left_types << left_type
|
||||||
match mut left {
|
match mut left {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
|
@ -5742,7 +5750,8 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||||
node.sym = c.table.get_type_symbol(c.unwrap_generic(c.expr(node.left)))
|
sym := c.table.get_type_symbol(c.unwrap_generic(c.expr(node.left)))
|
||||||
|
node.sym = *sym
|
||||||
if node.is_env {
|
if node.is_env {
|
||||||
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
||||||
c.error(err.msg, node.env_pos)
|
c.error(err.msg, node.env_pos)
|
||||||
|
@ -7770,7 +7779,7 @@ fn (mut c Checker) sql_expr(mut node ast.SqlExpr) ast.Type {
|
||||||
}
|
}
|
||||||
sym := c.table.get_type_symbol(node.table_expr.typ)
|
sym := c.table.get_type_symbol(node.table_expr.typ)
|
||||||
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
|
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
|
||||||
c.cur_orm_ts = sym
|
c.cur_orm_ts = *sym
|
||||||
info := sym.info as ast.Struct
|
info := sym.info as ast.Struct
|
||||||
fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, sym.name)
|
fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, sym.name)
|
||||||
mut sub_structs := map[int]ast.SqlExpr{}
|
mut sub_structs := map[int]ast.SqlExpr{}
|
||||||
|
@ -7868,7 +7877,7 @@ fn (mut c Checker) sql_stmt_line(mut node ast.SqlStmtLine) ast.Type {
|
||||||
}
|
}
|
||||||
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
|
c.ensure_type_exists(node.table_expr.typ, node.pos) or { return ast.void_type }
|
||||||
table_sym := c.table.get_type_symbol(node.table_expr.typ)
|
table_sym := c.table.get_type_symbol(node.table_expr.typ)
|
||||||
c.cur_orm_ts = table_sym
|
c.cur_orm_ts = *table_sym
|
||||||
if table_sym.info !is ast.Struct {
|
if table_sym.info !is ast.Struct {
|
||||||
c.error('unknown type `$table_sym.name`', node.pos)
|
c.error('unknown type `$table_sym.name`', node.pos)
|
||||||
return ast.void_type
|
return ast.void_type
|
||||||
|
@ -8071,7 +8080,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
c.check_valid_snake_case(node.name, 'function name', node.pos)
|
c.check_valid_snake_case(node.name, 'function name', node.pos)
|
||||||
}
|
}
|
||||||
if node.name == 'main.main' {
|
if node.name == 'main.main' {
|
||||||
c.main_fn_decl_node = node
|
c.main_fn_decl_node = *node
|
||||||
}
|
}
|
||||||
if node.return_type != ast.void_type {
|
if node.return_type != ast.void_type {
|
||||||
if ct_attr_idx := node.attrs.find_comptime_define() {
|
if ct_attr_idx := node.attrs.find_comptime_define() {
|
||||||
|
|
|
@ -76,7 +76,7 @@ mut:
|
||||||
cast_stack []ast.Type
|
cast_stack []ast.Type
|
||||||
call_stack []ast.CallExpr
|
call_stack []ast.CallExpr
|
||||||
is_vlines_enabled bool // is it safe to generate #line directives when -g is passed
|
is_vlines_enabled bool // is it safe to generate #line directives when -g is passed
|
||||||
sourcemap sourcemap.SourceMap // maps lines in generated javascrip file to original source files and line
|
sourcemap &sourcemap.SourceMap // maps lines in generated javascrip file to original source files and line
|
||||||
comptime_var_type_map map[string]ast.Type
|
comptime_var_type_map map[string]ast.Type
|
||||||
defer_ifdef string
|
defer_ifdef string
|
||||||
out strings.Builder = strings.new_builder(128)
|
out strings.Builder = strings.new_builder(128)
|
||||||
|
@ -98,6 +98,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||||
ns: 0
|
ns: 0
|
||||||
enable_doc: true
|
enable_doc: true
|
||||||
file: 0
|
file: 0
|
||||||
|
sourcemap: 0
|
||||||
}
|
}
|
||||||
g.doc = new_jsdoc(g)
|
g.doc = new_jsdoc(g)
|
||||||
// TODO: Add '[-no]-jsdoc' flag
|
// TODO: Add '[-no]-jsdoc' flag
|
||||||
|
|
|
@ -6,7 +6,7 @@ import v.token
|
||||||
|
|
||||||
pub struct Amd64 {
|
pub struct Amd64 {
|
||||||
mut:
|
mut:
|
||||||
g Gen
|
g &Gen
|
||||||
// arm64 specific stuff for code generation
|
// arm64 specific stuff for code generation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ enum Arm64Register {
|
||||||
|
|
||||||
pub struct Arm64 {
|
pub struct Arm64 {
|
||||||
mut:
|
mut:
|
||||||
g Gen
|
g &Gen
|
||||||
// arm64 specific stuff for code generation
|
// arm64 specific stuff for code generation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub const builtins = ['assert', 'print', 'eprint', 'println', 'eprintln', 'exit'
|
||||||
|
|
||||||
interface CodeGen {
|
interface CodeGen {
|
||||||
mut:
|
mut:
|
||||||
g Gen
|
g &Gen
|
||||||
gen_exit(mut g Gen, expr ast.Expr)
|
gen_exit(mut g Gen, expr ast.Expr)
|
||||||
// XXX WHY gen_exit fn (expr ast.Expr)
|
// XXX WHY gen_exit fn (expr ast.Expr)
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,14 @@ enum Size {
|
||||||
fn get_backend(arch pref.Arch) ?CodeGen {
|
fn get_backend(arch pref.Arch) ?CodeGen {
|
||||||
match arch {
|
match arch {
|
||||||
.arm64 {
|
.arm64 {
|
||||||
return Arm64{}
|
return Arm64{
|
||||||
|
g: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.amd64 {
|
.amd64 {
|
||||||
return Amd64{}
|
return Amd64{
|
||||||
|
g: 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -147,12 +147,12 @@ pub fn (mut p Parser) set_path(path string) {
|
||||||
}
|
}
|
||||||
before_dot_v := path.all_before_last('.v') // also works for .vv and .vsh
|
before_dot_v := path.all_before_last('.v') // also works for .vv and .vsh
|
||||||
language := before_dot_v.all_after_last('.')
|
language := before_dot_v.all_after_last('.')
|
||||||
langauge_with_underscore := before_dot_v.all_after_last('_')
|
language_with_underscore := before_dot_v.all_after_last('_')
|
||||||
if language == before_dot_v && langauge_with_underscore == before_dot_v {
|
if language == before_dot_v && language_with_underscore == before_dot_v {
|
||||||
p.file_backend_mode = .v
|
p.file_backend_mode = .v
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
actual_language := if language == before_dot_v { langauge_with_underscore } else { language }
|
actual_language := if language == before_dot_v { language_with_underscore } else { language }
|
||||||
match actual_language {
|
match actual_language {
|
||||||
'c' {
|
'c' {
|
||||||
p.file_backend_mode = .c
|
p.file_backend_mode = .c
|
||||||
|
|
Loading…
Reference in New Issue