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: adjustment needed for conversion rules for pointer conversions (?) #50815

Open
keep94 opened this issue Jan 26, 2022 · 7 comments
Open
Assignees
Labels
generics NeedsDecision
Milestone

Comments

@keep94
Copy link

@keep94 keep94 commented Jan 26, 2022

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

go1.18-16d6a5233a Tue Jan 25 00:39:08 2022 +0000. Using gotipplay.golang.org.

Does this issue reproduce with the latest release?

No.

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

I am using gotipplay.golang.org.

What did you do?

func Sum[Slice ~[]int](aslice Slice) int {
    p := (*[]int)(&aslice) // compile error: cannot convert &slice (value of type *Slice) to type *[]int
    result := 0
    for _, y := range *p {
        result += y
    }
    return result
}

What did you expect to see?

I expect p to be a *[]int

What did you see instead?

A compile error. cannot convert &slice (value of type *Slice) to type *[]int.

@randall77
Copy link
Contributor

@randall77 randall77 commented Jan 26, 2022

I think this should work. It does in the non-generic equivalent.
I suspect this is an interaction with structural types?
@griesemer @findleyr

@mknyszek mknyszek changed the title go1.18 generics: Pointer to slice type conversion fails with generics cmd/compile: Pointer to slice type conversion fails with generics Jan 26, 2022
@mknyszek mknyszek added the NeedsInvestigation label Jan 26, 2022
@mknyszek mknyszek added this to the Go1.18 milestone Jan 26, 2022
@mknyszek
Copy link
Contributor

@mknyszek mknyszek commented Jan 26, 2022

Based on @randall77's comment, tentatively marking as a release blocker.

Maybe this is go/types actually, I'm not sure. Feel free to update the title to better reflect where the issue lies.

@griesemer
Copy link
Contributor

@griesemer griesemer commented Jan 26, 2022

This is working as intended per the current rules and unrelated to structural types. Not a release blocker.

@griesemer griesemer added NeedsDecision and removed NeedsInvestigation release-blocker labels Jan 26, 2022
@griesemer
Copy link
Contributor

@griesemer griesemer commented Jan 26, 2022

We have special rules for generic conversions, but what we have here is not a generic conversion (at the top level). We convert a *Slice to a *[]int which is a pointer type conversion. The rule is:

ignoring struct tags (see below), x's type and T are pointer types that are not named types, and their pointer base types are not type parameters but have identical underlying types.

Here x's type is *Slice and T is *[]int. The pointer base types are Slice and []int, and Slice is a type parameter, so we can't convert. But even if we allowed a type parameter, this specific rule would fail because the underlying types (interface{ ~[]int } vs []int) don't match. We would need a new rule.

This case has come up before, and maybe we need a new rule for this case (resp. an adjustment of the new rules added for generic conversions.)

Leaving open for decision.

@ianlancetaylor

@griesemer griesemer changed the title cmd/compile: Pointer to slice type conversion fails with generics cmd/compile: adjustment needed for conversion rules for pointer conversions (?) Jan 26, 2022
@griesemer griesemer self-assigned this Jan 26, 2022
@ianlancetaylor ianlancetaylor added the generics label Jan 26, 2022
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 26, 2022

I think we should probably permit this, but perhaps not for 1.18.

@go101
Copy link

@go101 go101 commented Apr 4, 2022

It looks this pointer conversion rule for type parameters is more relaxed than ordinary types.
In the following code, the bar function fails to compile, but the foo function compiles okay.

package main

type Age int

func foo[T ~*Age](x T) *int {
	return (*int)(x) // okay
}

type AgePtr *Age

//func bar(x AgePtr) *int {
//	return (*int)(x) // error: cannot convert x (variable of type AgePtr) to type *int
//}

func main() {
	var x AgePtr
	var _ = foo[AgePtr](x)
}

@go101
Copy link

@go101 go101 commented Apr 4, 2022

The following function also doesn't compile.

func mud[T AgePtr](x T) *int {
	return (*int)(x) // error
}

So it looks the conversion rule in spec is not very accurate (or the foo function should not compile):

if T or x's type V are type parameters, x can also be converted to type T if one of the following conditions applies:

  • Both V and T are type parameters and a value of each type in V's type set can be converted to each type in T's type set.
  • Only V is a type parameter and a value of each type in V's type set can be converted to T.
  • Only T is a type parameter and x can be converted to each type in T's type set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
generics NeedsDecision
Projects
None yet
Development

No branches or pull requests

6 participants