From 0dd4e8c55d502f8f1d1131ed4c477d904a81ad76 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 11 Mar 2026 16:17:10 +0300 Subject: [PATCH] maps: compilation error when using `.to_array()` with a map whose value type is an interface (fixes #26567) --- vlib/maps/maps.v | 31 +++++++++++++++++++++++++------ vlib/maps/maps_test.v | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/vlib/maps/maps.v b/vlib/maps/maps.v index 4d1873009..9a212f1eb 100644 --- a/vlib/maps/maps.v +++ b/vlib/maps/maps.v @@ -5,8 +5,14 @@ pub fn filter[K, V](m map[K]V, f fn (key K, val V) bool) map[K]V { mut mp := map[K]V{} for k, v in m { - if f(k, v) { - mp[k] = v + $if V is $interface { + if f(k, unsafe { v }) { + mp[k] = v + } + } $else { + if f(k, v) { + mp[k] = v + } } } @@ -18,7 +24,11 @@ pub fn to_array[K, V, I](m map[K]V, f fn (key K, val V) I) []I { mut a := []I{cap: m.len} for k, v in m { - a << f(k, v) + $if V is $interface { + a << f(k, unsafe { v }) + } $else { + a << f(k, v) + } } return a @@ -29,7 +39,11 @@ pub fn flat_map[K, V, I](m map[K]V, f fn (key K, val V) []I) []I { mut a := []I{cap: m.len} for k, v in m { - a << f(k, v) + $if V is $interface { + a << f(k, unsafe { v }) + } $else { + a << f(k, v) + } } return a @@ -40,8 +54,13 @@ pub fn to_map[K, V, X, Y](m map[K]V, f fn (key K, val V) (X, Y)) map[X]Y { mut mp := map[X]Y{} for k, v in m { - x, y := f(k, v) - mp[x] = y + $if V is $interface { + x, y := f(k, unsafe { v }) + mp[x] = y + } $else { + x, y := f(k, v) + mp[x] = y + } } return mp diff --git a/vlib/maps/maps_test.v b/vlib/maps/maps_test.v index 85869e191..96eb6ff81 100644 --- a/vlib/maps/maps_test.v +++ b/vlib/maps/maps_test.v @@ -1,5 +1,17 @@ module maps +interface TestValue { + value() string +} + +struct TestValueImpl { + raw string +} + +fn (v TestValueImpl) value() string { + return v.raw +} + fn test_filter() { m1 := { 0: 'ab' @@ -36,6 +48,33 @@ fn test_to_array() { }) == ['abc', 'def', 'ghi'] } +fn test_helpers_with_interface_map_values() { + m1 := { + 'a': TestValue(TestValueImpl{'bc'}) + 'd': TestValue(TestValueImpl{'ef'}) + 'g': TestValue(TestValueImpl{'hi'}) + } + filtered := filter(m1, fn (k string, v TestValue) bool { + return k == 'a' || v.value() == 'ef' + }) + assert filtered.len == 2 + assert filtered['a'].value() == 'bc' + assert filtered['d'].value() == 'ef' + assert to_array(m1, fn (k string, v TestValue) string { + return '${k}${v.value()}' + }) == ['abc', 'def', 'ghi'] + assert flat_map[string, TestValue, string](m1, fn (k string, v TestValue) []string { + return [k, v.value()] + }) == ['a', 'bc', 'd', 'ef', 'g', 'hi'] + assert to_map[string, TestValue, string, string](m1, fn (k string, v TestValue) (string, string) { + return k, v.value() + }) == { + 'a': 'bc' + 'd': 'ef' + 'g': 'hi' + } +} + fn test_flat_map() { m1 := { 1: [2, 3] -- 2.39.5