v
v copied to clipboard
Wrong type is inferred in generic
Describe the bug
Passing &Item[K, V] to V in the Interface doesn't infer the right type.
Expected Behavior
Should correctly infer the type as &Item[K, V] and not as int.
Current Behavior
v run main.v
cache.v:63:14: error: `int` has no property `value`
61 | }
62 |
63 | return item.value, true
| ~~~~~
64 | }
65 |
cache.v:72:19: error: cannot use `&Item[string, int]` as `int` in argument 2 to `Interface<K,Item>[string, Item[string, int]].set`
70 | }
71 | item := new_item(key, val)
72 | c.cache.set(key, item)
| ~~~~
73 | }
74 |
cache.v:37:3: error: can not find method `get` on `Simple[string, int]`, needed for interface: `Interface<K,Item>`
35 | fn new_options[K, V]() &CacheOptions[K, V] {
36 | return &CacheOptions[K, V]{
37 | cache: new_simple[K, &Item[K, V]]()
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38 | }
39 | }
Reproduction Steps
module main
import sync
import time
pub interface Interface[K, V] {
get(key K) (V, bool)
set(key K, val V)
}
pub struct Item[K, V] {
key K
value V
}
fn new_item[K, V](key K, val V) &Item[K, V] {
return &Item[K, V]{
key: key
value: val
}
}
pub struct Cache[K, V] {
mut:
cache Interface[K, &Item[K, V]]
mu sync.Mutex
}
pub type CacheOption[K, V] = fn (o &CacheOptions[K, V])
struct CacheOptions[K, V] {
cache Interface[K, &Item[K, V]]
}
fn new_options[K, V]() &CacheOptions[K, V] {
return &CacheOptions[K, V]{
cache: new_simple[K, &Item[K, V]]()
}
}
pub fn new[K, V](opts ...CacheOption[K, V]) &Cache[K, V] {
mut o := new_options[K, V]()
for f in opts {
f[K, V](o)
}
cache := &Cache[K, V]{
cache: o.cache
}
return cache
}
pub fn (mut c Cache[K, V]) get(key K) (V, bool) {
c.mu.@lock()
defer {
c.mu.unlock()
}
item, ok := c.cache.get(key)
if !ok {
return Item[K, V]{}.value, false
}
return item.value, true
}
pub fn (mut c Cache[K, V]) set(key K, val V) {
c.mu.@lock()
defer {
c.mu.unlock()
}
item := new_item(key, val)
c.cache.set(key, item)
}
pub struct Simple[K, V] {
mut:
items map[K]&Entry[V]
}
struct Entry[V] {
val V
created_at time.Time
}
pub fn new_simple[K, V]() &Simple[K, V] {
return &Simple[K, V]{
items: map[K]&Entry[V]{}
}
}
pub fn (mut s Simple[K, V]) set(k K, v V) {
s.items[k] = &Entry[V]{
val: v
created_at: time.now()
}
}
pub fn (s Simple[K, V]) get(k K) (V, bool) {
got := s.items[k] or { return Entry[V]{}.val, false }
return got.val, true
}
fn main() {
mut c := new[string, int]()
c.set('a', 1)
v, ok := c.get('a')
println('${v} ${ok}')
}
Possible Solution
No response
Additional Information/Context
No response
V version
V 0.4.0 ecca3b1
Environment details (OS name and version, etc.)
V full version: V 0.4.0 7d6fd9d.ecca3b1
OS: macos, macOS, 13.4.1, 22F770820d
Processor: 12 cpus, 64bit, little endian, Apple M2 Pro
getwd: /Users/alex/dev/container
vexe: /opt/homebrew/Cellar/vlang/0.4/libexec/v
vexe mtime: 2023-08-02 03:18:51
vroot: OK, value: /opt/homebrew/Cellar/vlang/0.4/libexec
VMODULES: OK, value: /Users/alex/.vmodules
VTMP: OK, value: /tmp/v_501
Git version: git version 2.39.2 (Apple Git-143)
Git vroot status: weekly.2023.30-59-gecca3b15
.git/config present: true
CC version: Apple clang version 14.0.3 (clang-1403.0.22.14.1)
thirdparty/tcc status: thirdparty-macos-arm64 a668e5a0
The issue still persists.