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

runtime: duplicate key in map literal not detected #60161

Closed
tbruyelle opened this issue May 12, 2023 · 3 comments
Closed

runtime: duplicate key in map literal not detected #60161

tbruyelle opened this issue May 12, 2023 · 3 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.

Comments

@tbruyelle
Copy link
Contributor

What version of Go are you using (go version)?

$ go version
go version go1.20.3 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

Reproducible using https://go.dev/play/p/IV_Nb547iZY

What did you do?

Execute the following code :

package main

import "fmt"

func main() {
	type s struct{}
	m := map[s]int{
		{}: 1,
		{}: 2,
	}
	fmt.Println(m)
}

What did you expect to see?

An error duplicate key struct{} in map literal

What did you see instead?

The program executes without issue and prints the following:

map[{}:2]
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label May 12, 2023
@randall77
Copy link
Contributor

I don't think this is a bug. Confusing, I agree, but it follows the spec for composite literals.

It is an error to specify multiple elements with the same field name or constant key value. For non-constant map keys, see the section on evaluation order.

The crux of the question is whether the key you are using is a constant. https://go.dev/ref/spec#Constants lists the constants, and structs (empty or otherwise) are not constants. Even if they are obviously constant to you and me, they are not "Go constants" according to the spec.

For non-constants, we run each entry in the literal as an insert, in program order. There's no error possible in that scenario, we just get subsequent keys overwriting previous ones. That's why you get {}:2 at the end.

@randall77
Copy link
Contributor

I guess this could be a possible vet check?

@adonovan @timothy-king

@timothy-king
Copy link
Contributor

vet could warn about "ast"-identical, side effect free, non-pointer* struct keys in map composite literals. Seems feasible to do it.

It is not clear how often people would write map[struct{}]int though. This is an unclear way to write an optional int compared to struct{int; bool} or *int. For more complex examples does this happen in practice? So I am worried about meeting the frequency requirement for vet (README). Is there another example that happened in practice? Maybe this is just theoretically surprising?

[*] with maybe an exception for *struct{}.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime.
Projects
None yet
Development

No branches or pull requests

4 participants