fmt: keep constant sizes in struct field fixed array types (#9910)

pull/9921/head
Lukas Neubert 2021-04-28 21:11:15 +02:00 committed by GitHub
parent 626517f5f7
commit a065d014a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 11 deletions

View File

@ -30,8 +30,6 @@ const (
// TODOs and unfixed vfmt bugs
'vlib/builtin/int.v' /* TODO byteptr: vfmt converts `pub fn (nn byteptr) str() string {` to `nn &byte` and that conflicts with `nn byte` */,
'vlib/builtin/string_charptr_byteptr_helpers.v' /* TODO byteptr: a temporary shim to ease the byteptr=>&byte transition */,
'vlib/v/tests/array_append_short_struct_test.v', /* extra empty line */
'vlib/v/tests/fixed_array_const_size_test.v', /* fixed arr type is changed */
'vlib/v/tests/fn_high_test.v', /* param name removed */
'vlib/v/tests/fn_test.v', /* bad comment formatting */
'vlib/v/tests/generics_return_generics_struct_test.v', /* generic fn param removed */

View File

@ -577,10 +577,16 @@ pub fn (t &Table) array_cname(elem_type Type) string {
// array_fixed_source_name generates the original name for the v source.
// e. g. [16][8]int
[inline]
pub fn (t &Table) array_fixed_name(elem_type Type, size int) string {
pub fn (t &Table) array_fixed_name(elem_type Type, size int, size_expr Expr) string {
elem_type_sym := t.get_type_symbol(elem_type)
ptr := if elem_type.is_ptr() { '&'.repeat(elem_type.nr_muls()) } else { '' }
return '[$size]$ptr$elem_type_sym.name'
mut size_str := size.str()
if t.is_fmt {
if size_expr is Ident {
size_str = size_expr.name
}
}
return '[$size_str]$ptr$elem_type_sym.name'
}
[inline]
@ -760,8 +766,8 @@ pub fn (mut t Table) find_or_register_array_with_dims(elem_type Type, nr_dims in
return t.find_or_register_array(t.find_or_register_array_with_dims(elem_type, nr_dims - 1))
}
pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int) int {
name := t.array_fixed_name(elem_type, size)
pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int, size_expr Expr) int {
name := t.array_fixed_name(elem_type, size, size_expr)
cname := t.array_fixed_cname(elem_type, size)
// existing
existing_idx := t.type_idxs[name]
@ -776,6 +782,7 @@ pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int) int
info: ArrayFixed{
elem_type: elem_type
size: size
expr: size_expr
}
}
return t.register_type_symbol(array_fixed_type)
@ -983,7 +990,7 @@ pub fn (mut t Table) bitsize_to_type(bit_size int) Type {
if bit_size % 8 != 0 { // there is no way to do `i2131(32)` so this should never be reached
t.panic('compiler bug: bitsizes must be multiples of 8')
}
return new_type(t.find_or_register_array_fixed(byte_type, bit_size / 8))
return new_type(t.find_or_register_array_fixed(byte_type, bit_size / 8, EmptyExpr{}))
}
}
}

View File

@ -792,6 +792,7 @@ pub mut:
pub struct ArrayFixed {
pub:
size int
expr Expr // used by fmt for e.g. ´[my_const]byte´
pub mut:
elem_type Type
}
@ -874,7 +875,13 @@ pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string]
.array_fixed {
info := sym.info as ArrayFixed
elem_str := t.type_to_str_using_aliases(info.elem_type, import_aliases)
res = '[$info.size]$elem_str'
mut size_str := info.size.str()
if t.is_fmt {
if info.expr is Ident {
size_str = info.expr.name
}
}
res = '[$size_str]$elem_str'
}
.chan {
// TODO currently the `chan` struct in builtin is not considered a struct but a chan

View File

@ -3433,7 +3433,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type {
}
}
if array_init.is_fixed {
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len)
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len,
ast.EmptyExpr{})
if elem_type.has_flag(.generic) {
array_init.typ = ast.new_type(idx).set_flag(.generic)
} else {
@ -3479,7 +3480,8 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) ast.Type {
if fixed_size <= 0 {
c.error('fixed size cannot be zero or negative', init_expr.position())
}
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size)
idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size,
init_expr)
if array_init.elem_type.has_flag(.generic) {
array_init.typ = ast.new_type(idx).set_flag(.generic)
} else {

View File

@ -1,3 +1,10 @@
const size = 5
struct Foo {
bar [size]int
baz [5]int
}
fn foo() [1]f32 {
return [f32(0.0)]!
}

View File

@ -42,7 +42,7 @@ pub fn (mut p Parser) parse_array_type() ast.Type {
p.error_with_pos('fixed size cannot be zero or negative', size_expr.position())
}
// sym := p.table.get_type_symbol(elem_type)
idx := p.table.find_or_register_array_fixed(elem_type, fixed_size)
idx := p.table.find_or_register_array_fixed(elem_type, fixed_size, size_expr)
if elem_type.has_flag(.generic) {
return ast.new_type(idx).set_flag(.generic)
}