diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b82cfb214d..297f462761 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -239,6 +239,12 @@ pub fn (c mut Checker) selector_expr(selector_expr ast.SelectorExpr) table.Type if field := typ_sym.find_field(field_name) { return field.typ } + // variadic + if table.type_is_variadic(typ) { + if field_name == 'len' { + return table.int_type + } + } // check parent if typ_sym.parent_idx != 0 { parent := &c.table.types[typ_sym.parent_idx] diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 5aaaf9df4e..3541f40e52 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -205,7 +205,10 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { p.check(.ellipsis) is_variadic = true } - arg_type := p.parse_type() + mut arg_type := p.parse_type() + if is_variadic { + arg_type = table.type_to_variadic(arg_type) + } if p.tok.kind == .comma { if is_variadic { p.error('cannot use ...(variadic) with non-final parameter no $arg_no') @@ -234,7 +237,10 @@ fn (p mut Parser) fn_args() ([]ast.Arg,bool) { p.check(.ellipsis) is_variadic = true } - typ := p.parse_type() + mut typ := p.parse_type() + if is_variadic { + typ = table.type_to_variadic(typ) + } for arg_name in arg_names { args << ast.Arg{ name: arg_name diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 14e20b2128..cd1d2174ed 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -5,6 +5,7 @@ pub type Type int pub enum TypeExtra { unset optional + variadic } // return underlying TypeSymbol idx @@ -76,6 +77,16 @@ pub fn type_to_optional(t Type) Type { return type_set_extra(t, .optional) } +[inline] +pub fn type_is_variadic(t Type) bool { + return type_extra(t) == .variadic +} + +[inline] +pub fn type_to_variadic(t Type) Type { + return type_set_extra(t, .variadic) +} + // new type with idx of TypeSymbol, not pointer (nr_muls=0) [inline] pub fn new_type(idx int) Type {