v2: handle variadic in selector_expr

pull/3880/head
Joe Conigliaro 2020-02-29 19:04:47 +11:00
parent 71b5b0d955
commit 48f912c2e9
3 changed files with 25 additions and 2 deletions

View File

@ -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]

View File

@ -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

View File

@ -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 {