Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing a map to a generic argument changes a key value from int to an empty string #22035

Closed
prantlf opened this issue Aug 11, 2024 · 1 comment · Fixed by #22071
Closed
Assignees
Labels
Bug This tag is applied to issues which reports bugs. Comptime Features processed during compile time, like $if, $for, $env etc Generics[T] Bugs/feature requests, that are related to the V generics. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Checker Bugs/feature requests, that are related to the type checker.

Comments

@prantlf
Copy link

prantlf commented Aug 11, 2024

Describe the bug

  1. Let this map: { 'a': 1 }
  2. Enter the method marshal
  3. Which calls the method marshal_map
  4. And see it received as { 'a': '' }

This is simplified code. Runnable file is further below.

fn marshal[T](val T) {
  // received { 'a': 1 }
  marshal_map(val)
}

fn marshal_map[T](val map[string]T) {
  // received { 'a': '' }
}

marshal({ 'a': 1 })

Apparently, the value map[string]int was passed as map[string]string from marshal to marshal_map and the value of the key 'a' became the default value for string - ''.

Reproduction Steps

  1. Save the code below to the file marshal_test.v
  2. Run the command v marshal_test.v.
  3. Observe the following output:
test_marshal
 marshal: {'a': 1}
 marshal_map: {'a': ''}
test_marshal_map
 marshal_map: {'a': 1}

When marshal_map[T](val map[string]T) is called directly, the input map enters it correctly as map[string]int.

When marshal_map[T](val map[string]T) is called from marshal[T](val T), the input map enters it wrong as map[string]string.

The code of marshal_test.v, which is very simplified from a JSON parser and formatter:

module json

fn marshal[T](val T) {
	println(' marshal: ${val}')
	assert val['a'] == 1
	marshal_map(val)
}

fn marshal_map[T](val map[string]T) {
	println(' marshal_map: ${val}')
	// assert val['a'] == 1
}

fn test_marshal() {
	println('test_marshal')
	marshal({
		'a': 1
	})
}

fn test_marshal_map() {
	println('test_marshal_map')
	marshal_map({
		'a': 1
	})
}

Expected Behavior

When marshal_map[T](val map[string]T) is called from marshal[T](val T) with an input parameter of the type map[string]int, this type will be passed properly via marshal to marshal_map and the value of the key 'a' will be 1.

Current Behavior

I guess that map[string]int was converted to map[string]string and all key values were replaced by strings with default string values - ''.

Possible Solution

I wish I knew :-)

Additional Information/Context

When enabling the commented out assert in marshal_map:

`fn marshal_map[T](val map[string]T) {
	println(' marshal_map: ${val}')
	assert val['a'] == 1
}

The compiler fails with a complaint that the right argument was supposed to be a string, as expected from my assumption above:

marshal_test.v:11:12: error: infix expr: cannot use `int literal` (right expression) as `string`
    9 | fn marshal_map[T](val map[string]T) {
   10 |     println(' marshal_map: ${val}')
   11 |     assert val['a'] == 1
      |               ~~~~~~~~~~
   12 | }
   13 |

However, when changing the argument from 1 to '1':

fn marshal_map[T](val map[string]T) {
	println(' marshal_map: ${val}')
	assert val['a'] == '1'
}

The compiler fails again, now desiring an integer:

❯ v marshal_test.v
marshal_test.v:11:12: error: infix expr: cannot use `string` (right expression) as `int`
    9 | fn marshal_map[T](val map[string]T) {
   10 |     println(' marshal_map: ${val}')
   11 |     assert val['a'] == '1'
      |               ~~~~~~~~~~~~
   12 | }
   13 |

It doesn't know what it wants :-)

V version

V 0.4.7 ddb6685

Environment details (OS name and version, etc.)

V full version: V 0.4.7 ddb6685
OS: macos, macOS, 14.5, 23F79
Processor: 12 cpus, 64bit, little endian, Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz

getwd: /Users/ferdipr/Sources/github/v-bug
vexe: /Users/ferdipr/.vup/weekly.2024.32/v
vexe mtime: 2024-08-06 07:59:48

vroot: OK, value: /Users/ferdipr/.vup/weekly.2024.32
VMODULES: OK, value: /Users/ferdipr/.vmodules
VTMP: OK, value: /tmp/v_501

Git version: git version 2.46.0
Git vroot status: Error: fatal: not a git repository (or any of the parent directories): .git
.git/config present: false

CC version: Apple clang version 15.0.0 (clang-1500.3.9.4)
thirdparty/tcc: N/A

Note

You can use the 👍 reaction to increase the issue's priority for developers.

Please note that only the 👍 reaction to the issue itself counts as a vote.
Other reactions and those to comments will not be taken into account.

@prantlf prantlf added the Bug This tag is applied to issues which reports bugs. label Aug 11, 2024
@Cergoo
Copy link

Cergoo commented Aug 12, 2024

generics it is a very important thing to a lang.
It need to be worked out well, in theory it is just templates

@felipensp felipensp self-assigned this Aug 17, 2024
@felipensp felipensp added Generics[T] Bugs/feature requests, that are related to the V generics. Unit: Checker Bugs/feature requests, that are related to the type checker. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Comptime Features processed during compile time, like $if, $for, $env etc labels Aug 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs. Comptime Features processed during compile time, like $if, $for, $env etc Generics[T] Bugs/feature requests, that are related to the V generics. Unit: cgen Bugs/feature requests, that are related to the default C generating backend. Unit: Checker Bugs/feature requests, that are related to the type checker.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants