Repository navigation
checker: fix generic fn with generic fn call returning generic map (fix #20106) - #20150
Conversation
| // building a map of with all edges etc of a graph, represented from a matrix adjacency | ||
| // Input: matrix adjacency --> Output: edges list of src, dest and weight | ||
| fn build_map_edges_from_graph[T](g [][]T) map[T]EDGE { | ||
| fn build_map_edges_from_graph(g [][]int) map[int]EDGE { |
There was a problem hiding this comment.
hm, why are these a problem?
There was a problem hiding this comment.
Changing edges[j] to edges[T(j)] seems to fix compilation, without changing the header/making the function non generic 🤔 :
#1 14:00:56 ᛋ fix_generic_fn_call /v/oo❱./v run x.v > xres
#0 14:01:05 ᛋ fix_generic_fn_call /v/oo❱./v run examples/graphs/bellman-ford.v > yres
#0 14:01:09 ᛋ fix_generic_fn_call /v/oo❱diff xres yres
#0 14:01:18 ᛋ fix_generic_fn_call /v/oo❱
#0 14:01:20 ᛋ fix_generic_fn_call /v/oo❱
#0 14:01:20 ᛋ fix_generic_fn_call /v/oo❱colordiff examples/graphs/bellman-ford.v x.v
26c26
< fn build_map_edges_from_graph(g [][]int) map[int]EDGE {
---
> fn build_map_edges_from_graph[T](g [][]T) map[T]EDGE {
55c55
< fn bellman_ford(graph [][]int, src int) {
---
> fn bellman_ford[T](graph [][]T, src int) {
74,76c74,76
< mut u := edges[j].src
< mut v := edges[j].dest
< mut weight := edges[j].weight
---
> mut u := edges[T(j)].src
> mut v := edges[T(j)].dest
> mut weight := edges[T(j)].weight
88,90c88,90
< mut u := edges[j].src
< mut v := edges[j].dest
< mut weight := edges[j].weight
---
> mut u := edges[T(j)].src
> mut v := edges[T(j)].dest
> mut weight := edges[T(j)].weight
#1 14:01:23 ᛋ fix_generic_fn_call /v/oo❱
There was a problem hiding this comment.
I do not get why is j inferred to be an int literal though with this PR 🤔 .
There was a problem hiding this comment.
mut edges_map := map[int]EDGE{}
Because he has been internally confirmed as an int type, there is no need to be generic.
There was a problem hiding this comment.
there is no need to be generic
It should still work though, even when the function is generic, and it did compile before.
After mut edges_map := map[int]EDGE{}, then fn build_map_edges_from_graph[T](g [][]T) map[T]EDGE {, will mean that mut edges := build_map_edges_from_graph(graph) is map[int]EDGE, edges.len is int
for j in 0 .. n_edges { means that j is int too.
The errors however are for:
x.v:74:18: error: invalid key: expected `T`, not `int literal`
72 | for _ in 0 .. n_vertex {
73 | for j in 0 .. n_edges {
74 | mut u := edges[j].src
| ~~~
which is very confusing.
Where is that int literal coming from?
As I look at it, there should be no need for casting, and the non generic version works.
There was a problem hiding this comment.
In other words, I am worried that with this change, valid generic code, that compiled before, will require changes. Was it an error, that it compiled previously?
There was a problem hiding this comment.
- mut edges := build_map_edges_from_graph(graph)
+ mut edges := build_map_edges_from_graph[int](graph)
also fixes all compilation errors in this PR for examples/graphs/bellman-ford.v, with a one line change, without needing to change the function declarations.
| } | ||
|
|
||
| fn start[T, R](app T, otherthing R) R { | ||
| fn start[T, R](app T, otherthing R) string { |
There was a problem hiding this comment.
I feel this didn't need any change.
|
I still have an uneasy feeling about this change, given the confusing However, I could not make a clearer and smaller reproduction, and the PR does fix another clearly useful case, so I am merging it. |
This PR fix generic fn with generic fn call returning generic map (fix #20106).