From 09f6cd6a758f710c91b8def63d196278e9c07e07 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Sat, 9 May 2020 23:45:41 +0200 Subject: [PATCH] parser/checker: [ref_only] attribute --- vlib/v/ast/ast.v | 1 + vlib/v/checker/checker.v | 6 ++++++ vlib/v/parser/struct.v | 2 ++ vlib/v/table/atypes.v | 11 ++++++----- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 814c046210..9614c9ec15 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -153,6 +153,7 @@ pub: is_c bool is_js bool is_union bool + attr string } pub struct InterfaceDecl { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 0b4c227e81..e0676782e1 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -232,6 +232,12 @@ pub fn (mut c Checker) struct_decl(decl ast.StructDecl) { if sym.kind == .placeholder && !decl.is_c && !sym.name.starts_with('C.') { c.error('unknown type `$sym.name`', field.pos) } + if sym.kind == .struct_ { + info:=sym.info as table.Struct + if info.is_ref_only && !field.typ.is_ptr() { + c.error('`$sym.name` type can only be used as a reference: `&$sym.name`', field.pos) + } + } if field.has_default_expr { c.expected_type = field.typ field_expr_type := c.expr(field.default_expr) diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index 218ab42a0e..6e3521cb04 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -166,6 +166,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { fields: fields is_typedef: is_typedef is_union: is_union + is_ref_only: p.attr == 'ref_only' } mod: p.mod is_public: is_pub @@ -193,6 +194,7 @@ fn (mut p Parser) struct_decl() ast.StructDecl { is_c: is_c is_js: is_js is_union: is_union + attr: p.attr } } diff --git a/vlib/v/table/atypes.v b/vlib/v/table/atypes.v index 83183d3177..230dfea698 100644 --- a/vlib/v/table/atypes.v +++ b/vlib/v/table/atypes.v @@ -531,9 +531,10 @@ pub fn (kinds []Kind) str() string { pub struct Struct { pub mut: - fields []Field - is_typedef bool // C. [typedef] - is_union bool + fields []Field + is_typedef bool // C. [typedef] + is_union bool + is_ref_only bool } pub struct Interface { @@ -641,7 +642,7 @@ pub fn (table &Table) type_to_str(t Type) string { return res } -pub fn(t &Table) fn_to_str(func &Fn) string { +pub fn (t &Table) fn_to_str(func &Fn) string { mut sb := strings.new_builder(20) sb.write('${func.name}(') for i in 1 .. func.args.len { @@ -655,7 +656,7 @@ pub fn(t &Table) fn_to_str(func &Fn) string { } } sb.write(')') - if func.return_type != table.void_type { + if func.return_type != void_type { sb.write(' ${t.type_to_str(func.return_type)}') } return sb.str()