checker: no longer allow automatic dereferncing in `a = b`
parent
d1e9aa49ea
commit
ab3adf3346
|
@ -131,7 +131,7 @@ fn break_if_debugger_attached() {
|
|||
unsafe {
|
||||
mut 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)
|
||||
[inline]
|
||||
pub fn run(desc &C.sapp_desc) {
|
||||
g_desc = desc
|
||||
g_desc = *desc
|
||||
C.sapp_run(desc)
|
||||
}
|
||||
|
||||
|
|
|
@ -122,28 +122,33 @@ pub mut:
|
|||
typ Type
|
||||
}
|
||||
|
||||
pub fn (f Fn) new_method_with_receiver_type(new_type Type) Fn {
|
||||
mut new_method := f
|
||||
new_method.params = f.params.clone()
|
||||
for i in 1 .. new_method.params.len {
|
||||
if new_method.params[i].typ == new_method.params[0].typ {
|
||||
new_method.params[i].typ = new_type
|
||||
pub fn (f &Fn) new_method_with_receiver_type(new_type Type) Fn {
|
||||
unsafe {
|
||||
mut new_method := f
|
||||
new_method.params = f.params.clone()
|
||||
for i in 1 .. new_method.params.len {
|
||||
if new_method.params[i].typ == new_method.params[0].typ {
|
||||
new_method.params[i].typ = new_type
|
||||
}
|
||||
}
|
||||
new_method.params[0].typ = new_type
|
||||
|
||||
return *new_method
|
||||
}
|
||||
new_method.params[0].typ = new_type
|
||||
return new_method
|
||||
}
|
||||
|
||||
pub fn (f FnDecl) new_method_with_receiver_type(new_type Type) FnDecl {
|
||||
mut new_method := f
|
||||
new_method.params = f.params.clone()
|
||||
for i in 1 .. new_method.params.len {
|
||||
if new_method.params[i].typ == new_method.params[0].typ {
|
||||
new_method.params[i].typ = new_type
|
||||
pub fn (f &FnDecl) new_method_with_receiver_type(new_type Type) FnDecl {
|
||||
unsafe {
|
||||
mut new_method := f
|
||||
new_method.params = f.params.clone()
|
||||
for i in 1 .. new_method.params.len {
|
||||
if new_method.params[i].typ == new_method.params[0].typ {
|
||||
new_method.params[i].typ = new_type
|
||||
}
|
||||
}
|
||||
new_method.params[0].typ = new_type
|
||||
return *new_method
|
||||
}
|
||||
new_method.params[0].typ = new_type
|
||||
return new_method
|
||||
}
|
||||
|
||||
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)})'
|
||||
}
|
||||
|
||||
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
|
||||
pub fn (t Type) debug() []string {
|
||||
mut res := []string{}
|
||||
|
@ -309,6 +314,11 @@ pub fn (typ Type) is_pointer() bool {
|
|||
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]
|
||||
pub fn (typ Type) is_float() bool {
|
||||
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
|
||||
// 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 {
|
||||
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
|
||||
match mut left {
|
||||
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 {
|
||||
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 {
|
||||
env_value := util.resolve_env_value("\$env('$node.args_var')", false) or {
|
||||
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)
|
||||
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
|
||||
fields := c.fetch_and_verify_orm_fields(info, node.table_expr.pos, sym.name)
|
||||
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 }
|
||||
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 {
|
||||
c.error('unknown type `$table_sym.name`', node.pos)
|
||||
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)
|
||||
}
|
||||
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 ct_attr_idx := node.attrs.find_comptime_define() {
|
||||
|
|
|
@ -76,7 +76,7 @@ mut:
|
|||
cast_stack []ast.Type
|
||||
call_stack []ast.CallExpr
|
||||
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
|
||||
defer_ifdef string
|
||||
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
|
||||
enable_doc: true
|
||||
file: 0
|
||||
sourcemap: 0
|
||||
}
|
||||
g.doc = new_jsdoc(g)
|
||||
// TODO: Add '[-no]-jsdoc' flag
|
||||
|
@ -185,7 +186,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
|||
// out += 'const $name = (function ('
|
||||
mut namespace := g.namespaces[node.name]
|
||||
|
||||
|
||||
|
||||
if g.pref.sourcemap {
|
||||
// calculate current output start line
|
||||
mut current_line := u32(out.count('\n') + 1)
|
||||
|
@ -206,7 +207,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
|||
sm_pos = sourcemap_ns_entry.ns_pos
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// public scope
|
||||
out += '\n'
|
||||
|
|
|
@ -6,7 +6,7 @@ import v.token
|
|||
|
||||
pub struct Amd64 {
|
||||
mut:
|
||||
g Gen
|
||||
g &Gen
|
||||
// arm64 specific stuff for code generation
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ enum Arm64Register {
|
|||
|
||||
pub struct Arm64 {
|
||||
mut:
|
||||
g Gen
|
||||
g &Gen
|
||||
// arm64 specific stuff for code generation
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ pub const builtins = ['assert', 'print', 'eprint', 'println', 'eprintln', 'exit'
|
|||
|
||||
interface CodeGen {
|
||||
mut:
|
||||
g Gen
|
||||
g &Gen
|
||||
gen_exit(mut g Gen, expr ast.Expr)
|
||||
// XXX WHY gen_exit fn (expr ast.Expr)
|
||||
}
|
||||
|
@ -58,10 +58,14 @@ enum Size {
|
|||
fn get_backend(arch pref.Arch) ?CodeGen {
|
||||
match arch {
|
||||
.arm64 {
|
||||
return Arm64{}
|
||||
return Arm64{
|
||||
g: 0
|
||||
}
|
||||
}
|
||||
.amd64 {
|
||||
return Amd64{}
|
||||
return Amd64{
|
||||
g: 0
|
||||
}
|
||||
}
|
||||
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
|
||||
language := before_dot_v.all_after_last('.')
|
||||
langauge_with_underscore := before_dot_v.all_after_last('_')
|
||||
if language == before_dot_v && langauge_with_underscore == before_dot_v {
|
||||
language_with_underscore := before_dot_v.all_after_last('_')
|
||||
if language == before_dot_v && language_with_underscore == before_dot_v {
|
||||
p.file_backend_mode = .v
|
||||
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 {
|
||||
'c' {
|
||||
p.file_backend_mode = .c
|
||||
|
|
Loading…
Reference in New Issue