mirror of
https://github.com/vlang/v.git
synced 2025-09-16 16:02:29 +03:00
cgen: fix .sort(), and .sorted() method calls, when array aliases are used as receivers (fix #20075) (#20081)
This commit is contained in:
parent
4a37403a30
commit
5ee963837a
3 changed files with 34 additions and 5 deletions
|
@ -1649,7 +1649,7 @@ fn (mut c Checker) cast_to_fixed_array_ret(typ ast.Type, sym ast.TypeSymbol) ast
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if a type from another module is is expected and visible(`is_pub`)
|
// checks if a type from another module is as expected and visible(`is_pub`)
|
||||||
fn (mut c Checker) check_type_and_visibility(name string, type_idx int, expected_kind &ast.Kind, pos &token.Pos) bool {
|
fn (mut c Checker) check_type_and_visibility(name string, type_idx int, expected_kind &ast.Kind, pos &token.Pos) bool {
|
||||||
mut sym := c.table.sym_by_idx(type_idx)
|
mut sym := c.table.sym_by_idx(type_idx)
|
||||||
if sym.kind == .alias {
|
if sym.kind == .alias {
|
||||||
|
|
|
@ -590,9 +590,21 @@ fn (mut g Gen) gen_array_sorted(node ast.CallExpr) {
|
||||||
info := sym.info as ast.Array
|
info := sym.info as ast.Array
|
||||||
depth := g.get_array_depth(info.elem_type)
|
depth := g.get_array_depth(info.elem_type)
|
||||||
|
|
||||||
g.write('${atype} ${past.tmp_var} = array_clone_to_depth(ADDR(${atype},')
|
deref_field := if node.receiver_type.nr_muls() > node.left_type.nr_muls()
|
||||||
g.expr(node.left)
|
&& node.left_type.is_ptr() {
|
||||||
g.writeln('), ${depth});')
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
if !deref_field {
|
||||||
|
g.write('${atype} ${past.tmp_var} = array_clone_to_depth(ADDR(${atype},')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.writeln('), ${depth});')
|
||||||
|
} else {
|
||||||
|
g.write('${atype} ${past.tmp_var} = array_clone_to_depth(')
|
||||||
|
g.expr(node.left)
|
||||||
|
g.writeln(', ${depth});')
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
node.left = ast.Expr(ast.Ident{
|
node.left = ast.Expr(ast.Ident{
|
||||||
|
@ -708,7 +720,12 @@ fn (mut g Gen) gen_array_sort(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) gen_array_sort_call(node ast.CallExpr, compare_fn string) {
|
fn (mut g Gen) gen_array_sort_call(node ast.CallExpr, compare_fn string) {
|
||||||
mut deref_field := g.dot_or_ptr(node.left_type)
|
deref_field := if node.receiver_type.nr_muls() > node.left_type.nr_muls()
|
||||||
|
&& node.left_type.is_ptr() {
|
||||||
|
g.dot_or_ptr(node.left_type.deref())
|
||||||
|
} else {
|
||||||
|
g.dot_or_ptr(node.left_type)
|
||||||
|
}
|
||||||
// eprintln('> qsort: pointer $node.left_type | deref_field: `$deref_field`')
|
// eprintln('> qsort: pointer $node.left_type | deref_field: `$deref_field`')
|
||||||
g.empty_line = true
|
g.empty_line = true
|
||||||
g.write('qsort(')
|
g.write('qsort(')
|
||||||
|
|
|
@ -73,3 +73,15 @@ fn test_string_eq_method_with_interface() {
|
||||||
}
|
}
|
||||||
assert false
|
assert false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test deref when alias as receiver of methods
|
||||||
|
type Array = []int
|
||||||
|
|
||||||
|
pub fn (mut arr Array) alias_as_receiver_deref() []int {
|
||||||
|
return arr.sorted(b < a)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_alias_as_receiver_deref() {
|
||||||
|
mut arr := Array([1, 2, 3])
|
||||||
|
assert arr.alias_as_receiver_deref() == [3, 2, 1]
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue