From 73fd4396c3fa471a267826d4031dbc35b904cc9a Mon Sep 17 00:00:00 2001
From: yuyi <yuyi98@163.com>
Date: Mon, 18 Jan 2021 13:03:03 +0800
Subject: [PATCH] parser: fix fixed array using const size (fix #8144) (#8161)

---
 vlib/v/parser/parse_type.v                 | 30 +++++++++++++++++++---
 vlib/v/tests/fixed_array_const_size_test.v | 15 +++++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)
 create mode 100644 vlib/v/tests/fixed_array_const_size_test.v

diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v
index 557c6db4cb..2d817455f5 100644
--- a/vlib/v/parser/parse_type.v
+++ b/vlib/v/parser/parse_type.v
@@ -5,13 +5,35 @@ module parser
 
 import v.table
 import v.util
+import v.ast
 
 pub fn (mut p Parser) parse_array_type() table.Type {
 	p.check(.lsbr)
 	// fixed array
-	if p.tok.kind == .number {
-		size := p.tok.lit.int()
-		p.next()
+	if p.tok.kind in [.number, .name] {
+		mut fixed_size := 0
+		size_expr := p.expr(0)
+		match size_expr {
+			ast.IntegerLiteral {
+				fixed_size = size_expr.val.int()
+			}
+			ast.Ident {
+				if const_field := p.global_scope.find_const('${p.mod}.$size_expr.name') {
+					if const_field.expr is ast.IntegerLiteral {
+						fixed_size = const_field.expr.val.int()
+					} else {
+						p.error_with_pos('non existent integer const $size_expr.name while initializing the size of a static array',
+							size_expr.pos)
+					}
+				} else {
+					p.error_with_pos('non existent integer const $size_expr.name while initializing the size of a static array',
+						size_expr.pos)
+				}
+			}
+			else {
+				p.error('expecting `int` for fixed size')
+			}
+		}
 		p.check(.rsbr)
 		elem_type := p.parse_type()
 		if elem_type.idx() == 0 {
@@ -19,7 +41,7 @@ pub fn (mut p Parser) parse_array_type() table.Type {
 			return 0
 		}
 		// sym := p.table.get_type_symbol(elem_type)
-		idx := p.table.find_or_register_array_fixed(elem_type, size)
+		idx := p.table.find_or_register_array_fixed(elem_type, fixed_size)
 		return table.new_type(idx)
 	}
 	// array
diff --git a/vlib/v/tests/fixed_array_const_size_test.v b/vlib/v/tests/fixed_array_const_size_test.v
new file mode 100644
index 0000000000..d13171fa99
--- /dev/null
+++ b/vlib/v/tests/fixed_array_const_size_test.v
@@ -0,0 +1,15 @@
+const (
+	size = 5
+)
+
+struct Foo {
+	bar [size]byte
+}
+
+fn test_fixed_array_const_size() {
+	a := Foo{}
+	println(a)
+	assert a == Foo{
+		bar: [byte(0), 0, 0, 0, 0]!
+	}
+}