checker: do not require ref field init with update expr

pull/8159/head
Alexander Medvednikov 2021-01-17 06:24:03 +01:00
parent df39e7001c
commit 2b058edc98
2 changed files with 34 additions and 27 deletions

View File

@ -633,7 +633,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
if field.has_default_expr || field.name in inited_fields { if field.has_default_expr || field.name in inited_fields {
continue continue
} }
if field.typ.is_ptr() && !c.pref.translated { if field.typ.is_ptr() && !struct_init.has_update_expr && !c.pref.translated {
c.error('reference field `${type_sym.name}.$field.name` must be initialized', c.error('reference field `${type_sym.name}.$field.name` must be initialized',
struct_init.pos) struct_init.pos)
} }
@ -3299,29 +3299,7 @@ pub fn (mut c Checker) expr(node ast.Expr) table.Type {
return c.at_expr(mut node) return c.at_expr(mut node)
} }
ast.ComptimeCall { ast.ComptimeCall {
node.sym = c.table.get_type_symbol(c.unwrap_generic(c.expr(node.left))) return c.comptime_call(mut node)
if node.is_embed {
c.file.embedded_files << node.embed_file
return c.table.find_type_idx('v.embed_file.EmbedFileData')
}
if node.is_vweb {
// TODO assoc parser bug
pref := *c.pref
pref2 := {
pref |
is_vweb: true
}
mut c2 := new_checker(c.table, pref2)
c2.check(node.vweb_tmpl)
c.warnings << c2.warnings
c.errors << c2.errors
c.nr_warnings += c2.nr_warnings
c.nr_errors += c2.nr_errors
}
if node.method_name == 'html' {
return c.table.find_type_idx('vweb.Result')
}
return table.string_type
} }
ast.ComptimeSelector { ast.ComptimeSelector {
node.left_type = c.unwrap_generic(c.expr(node.left)) node.left_type = c.unwrap_generic(c.expr(node.left))
@ -3556,6 +3534,32 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type {
return node.typ return node.typ
} }
fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) table.Type {
node.sym = c.table.get_type_symbol(c.unwrap_generic(c.expr(node.left)))
if node.is_embed {
c.file.embedded_files << node.embed_file
return c.table.find_type_idx('v.embed_file.EmbedFileData')
}
if node.is_vweb {
// TODO assoc parser bug
pref := *c.pref
pref2 := {
pref |
is_vweb: true
}
mut c2 := new_checker(c.table, pref2)
c2.check(node.vweb_tmpl)
c.warnings << c2.warnings
c.errors << c2.errors
c.nr_warnings += c2.nr_warnings
c.nr_errors += c2.nr_errors
}
if node.method_name == 'html' {
return c.table.find_type_idx('vweb.Result')
}
return table.string_type
}
fn (mut c Checker) at_expr(mut node ast.AtExpr) table.Type { fn (mut c Checker) at_expr(mut node ast.AtExpr) table.Type {
match node.kind { match node.kind {
.fn_name { .fn_name {

View File

@ -156,8 +156,8 @@ fn (mut p Parser) comp_call() ast.ComptimeCall {
println('\n\n') println('\n\n')
} }
mut file := parse_comptime(v_code, p.table, p.pref, scope, p.global_scope) mut file := parse_comptime(v_code, p.table, p.pref, scope, p.global_scope)
file = { file = ast.File{
file | ...file
path: tmpl_path path: tmpl_path
} }
// copy vars from current fn scope into vweb_tmpl scope // copy vars from current fn scope into vweb_tmpl scope
@ -170,7 +170,10 @@ fn (mut p Parser) comp_call() ast.ComptimeCall {
if obj is ast.Var { if obj is ast.Var {
mut v := obj mut v := obj
v.pos = stmt.body_pos v.pos = stmt.body_pos
tmpl_scope.register(v) tmpl_scope.register(ast.Var{
...v
is_used: true
})
// set the controller action var to used // set the controller action var to used
// if it's unused in the template it will warn // if it's unused in the template it will warn
v.is_used = true v.is_used = true