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

cmd/compile: slice constraints prevent indexing #52129

Closed
jfcg opened this issue Apr 3, 2022 · 5 comments
Closed

cmd/compile: slice constraints prevent indexing #52129

jfcg opened this issue Apr 3, 2022 · 5 comments

Comments

@jfcg
Copy link

jfcg commented Apr 3, 2022

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

1.18

Does this issue reproduce with the latest release?

yes

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

Linux Amd64

What did you do?

Tried to go build:

func presort1[Slice ~[]int | ~[]uint](slc Slice) {
	l, h := 0, 10
	for h < len(slc) {
		if slc[h] < slc[l] {
			slc[h], slc[l] = slc[l], slc[h]
		}
		l++
		h++
	}
}

type MyInt int
type MySlice []MyInt

func presort2(slc MySlice) {
	l, h := 0, 10
	for h < len(slc) {
		if slc[h] < slc[l] {
			slc[h], slc[l] = slc[l], slc[h]
		}
		l++
		h++
	}
}

What did you expect to see?

No errors.

What did you see instead?

presort1 does not compile with error

invalid operation: cannot index slc (variable of type Slice constrained by ~[]int|~[]uint)

presort2 is fine

@rittneje
Copy link

rittneje commented Apr 3, 2022

As a workaround, this works:

func presort1[T ~int | ~uint](slc []T) {
	l, h := 0, 10
	for h < len(slc) {
		if slc[h] < slc[l] {
			slc[h], slc[l] = slc[l], slc[h]
		}
		l++
		h++
	}
}

@jfcg
Copy link
Author

jfcg commented Apr 3, 2022

That has a narrower scope, cannot accept MySlice for example

@rittneje
Copy link

rittneje commented Apr 3, 2022

No, that still works. https://go.dev/play/p/h3nx0geBIRf

@ianlancetaylor ianlancetaylor changed the title cmd/go: slice constraints prevent indexing cmd/compile: slice constraints prevent indexing Apr 3, 2022
@go101
Copy link

go101 commented Apr 3, 2022

There is a principle rule: the type of a value must be a specified type, which might be either an ordinary type or a type parameter. In the first comment, slc[h] and slc[l] both might be int or uint, which breaks this rule.

[Edit] Another implementation variation:

func presort1[T ~int | ~uint, S ~[]T](slc S) {
	l, h := 0, 10
	for h < len(slc) {
		if slc[h] < slc[l] {
			slc[h], slc[l] = slc[l], slc[h]
		}
		l++
		h++
	}
}

@ianlancetaylor
Copy link
Contributor

This is expected according to the current spec. We may change it some day, but not soon. Closing.

@golang golang locked and limited conversation to collaborators Apr 4, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants