checker, cgen: fix generic fn with array and fixed array arguments (#14385)
parent
d679146a80
commit
3c95504a35
|
@ -3864,11 +3864,9 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||||
mut typ := c.expr(node.left)
|
mut typ := c.expr(node.left)
|
||||||
mut typ_sym := c.table.final_sym(typ)
|
mut typ_sym := c.table.final_sym(typ)
|
||||||
node.left_type = typ
|
node.left_type = typ
|
||||||
for {
|
|
||||||
match typ_sym.kind {
|
match typ_sym.kind {
|
||||||
.map {
|
.map {
|
||||||
node.is_map = true
|
node.is_map = true
|
||||||
break
|
|
||||||
}
|
}
|
||||||
.array {
|
.array {
|
||||||
node.is_array = true
|
node.is_array = true
|
||||||
|
@ -3876,28 +3874,15 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) ast.Type {
|
||||||
c.error('custom error handling on range expressions for arrays is not supported yet.',
|
c.error('custom error handling on range expressions for arrays is not supported yet.',
|
||||||
node.or_expr.pos)
|
node.or_expr.pos)
|
||||||
}
|
}
|
||||||
break
|
|
||||||
}
|
}
|
||||||
.array_fixed {
|
.array_fixed {
|
||||||
node.is_farray = true
|
node.is_farray = true
|
||||||
break
|
|
||||||
}
|
}
|
||||||
.any {
|
.any {
|
||||||
gname := typ_sym.name
|
|
||||||
typ = c.unwrap_generic(typ)
|
typ = c.unwrap_generic(typ)
|
||||||
node.left_type = typ
|
|
||||||
typ_sym = c.table.final_sym(typ)
|
typ_sym = c.table.final_sym(typ)
|
||||||
if typ.is_ptr() {
|
|
||||||
continue
|
|
||||||
} else {
|
|
||||||
c.error('generic type $gname does not support indexing, pass an array, or a reference instead, e.g. []$gname or &$gname',
|
|
||||||
node.pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {}
|
||||||
}
|
}
|
||||||
if typ_sym.kind !in [.array, .array_fixed, .string, .map] && !typ.is_ptr()
|
if typ_sym.kind !in [.array, .array_fixed, .string, .map] && !typ.is_ptr()
|
||||||
&& typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic) {
|
&& typ !in [ast.byteptr_type, ast.charptr_type] && !typ.has_flag(.variadic) {
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
vlib/v/checker/tests/generic_param_used_as_an_array_err.vv:2:10: error: generic type T does not support indexing, pass an array, or a reference instead, e.g. []T or &T
|
|
||||||
1 | fn test<T>(arr T) {
|
|
||||||
2 | a := arr[1]
|
|
||||||
| ~~~
|
|
||||||
3 | println(a)
|
|
||||||
4 | }
|
|
|
@ -1,12 +0,0 @@
|
||||||
fn test<T>(arr T) {
|
|
||||||
a := arr[1]
|
|
||||||
println(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
a := [1, 2, 3]!
|
|
||||||
test(a)
|
|
||||||
|
|
||||||
b := ['a', 'b', 'c']!
|
|
||||||
test(b)
|
|
||||||
}
|
|
|
@ -10,7 +10,7 @@ fn (mut g Gen) index_expr(node ast.IndexExpr) {
|
||||||
if node.index is ast.RangeExpr {
|
if node.index is ast.RangeExpr {
|
||||||
g.range_expr(node, node.index)
|
g.range_expr(node, node.index)
|
||||||
} else {
|
} else {
|
||||||
sym := g.table.final_sym(node.left_type)
|
sym := g.table.final_sym(g.unwrap_generic(node.left_type))
|
||||||
if sym.kind == .array {
|
if sym.kind == .array {
|
||||||
g.index_of_array(node, sym)
|
g.index_of_array(node, sym)
|
||||||
} else if sym.kind == .array_fixed {
|
} else if sym.kind == .array_fixed {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fn show_element<T>(arr &T) string {
|
fn show_element<T>(arr T) string {
|
||||||
return unsafe { '${arr[1]}' }
|
return '${arr[1]}'
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_generic_with_fixed_array_type() {
|
fn test_generic_with_fixed_array_type() {
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
6
|
|
@ -0,0 +1,15 @@
|
||||||
|
fn main() {
|
||||||
|
mut a := [1, 2, 3]
|
||||||
|
mut b := [4, 5, 6]!
|
||||||
|
|
||||||
|
func(mut a)
|
||||||
|
func(mut b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn func<T>(mut t T) {
|
||||||
|
$if T is $Array {
|
||||||
|
for i in 0 .. t.len {
|
||||||
|
println(t[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue