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: build failed #50660

Closed
cuiweixie opened this issue Jan 17, 2022 · 11 comments
Closed

cmd/compile: build failed #50660

cuiweixie opened this issue Jan 17, 2022 · 11 comments
Labels
NeedsInvestigation release-blocker
Milestone

Comments

@cuiweixie
Copy link
Contributor

@cuiweixie cuiweixie commented Jan 17, 2022

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

$ go version
go version devel go1.18-897b3da2e0 Mon Jan 17 09:23:25 2022 +0000 darwin/arm64

Does this issue reproduce with the latest release?

no

What did you do?

example1 :


import (
	"fmt"
)


type I int64

func(i I) Do() int64 {
	return int64(i)
}

type Int interface {
	int32 | int64
}

type Doer[T Int] interface {
	Do() T
}

func Specialize[T Int](v Doer[T]) {
	switch v.(type) {
	case Doer[int32]:
		fmt.Println("int32!")
	case Doer[int64]:
		fmt.Println("int64!")
	}
}

func main() {
	var i Doer[int64]
	i = I(1)
	Specialize[int64](i)
}

example2:

package main

import (
	"fmt"
)


type I int64

func(i I) Do() int64 {
	return int64(i)
}

type Int interface {
	int32 | int64
}

type Doer[T Int] interface {
	Do() T
}

func Specialize[T Int](v Doer[T]) {
	switch v1 := v.(type) {
	case Doer[int32]:
		var v2 Doer[T]
		v2 = v1
		fmt.Println("int32!", v1)
	case Doer[int64]:
		fmt.Println("int64!")
	}
}

func main() {
	var i Doer[int64]
	i = I(1)
	Specialize[int64](i)
} 

What did you expect to see?

example1:
go run success!
example2:
go run success!

What did you see instead?

example1:
go run success!
example2:

# command-line-arguments
./main.go:26:8: cannot use v1 (variable of type Doer[int32]) as type Doer[T] in assignment:
        Doer[int32] does not implement Doer[T] (wrong type for Do method)
                have Do() int32 at ./main.go:19:2
                want Do() T
@cuiweixie
Copy link
Contributor Author

@cuiweixie cuiweixie commented Jan 17, 2022

when i try to fix #50658 , i found this will failed too.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 17, 2022

CC @griesemer @findleyr

Probably the same problem as #50658.

@ianlancetaylor ianlancetaylor added NeedsInvestigation release-blocker labels Jan 17, 2022
@ianlancetaylor ianlancetaylor added this to the Go1.18 milestone Jan 17, 2022
@erifan
Copy link
Contributor

@erifan erifan commented Jan 18, 2022

var v2 Doer[T]
v2 = v1

Should this be a "declared but not used" error ?

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 18, 2022

@erifan Yes, looks like it. But that is a separate issue.

@erifan
Copy link
Contributor

@erifan erifan commented Jan 18, 2022

@ianlancetaylor If we rule out this problem, then this issue and #50658 seem to be the same, then we can close this.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 18, 2022

The error message here (cannot use v1 (variable of type Doer[int32]) as type Doer[T] in assignment) is not the same as the error message in #50658 (impossible type assertion). I would not be surprised if they are the same underlying problem, but let's verify that before we close this issue. Thanks.

@cuiweixie
Copy link
Contributor Author

@cuiweixie cuiweixie commented Jan 18, 2022

run example1 success.
according to #50658 , example1 will failed.
#50658 failed in

"impossible type assertion: no type can implement both %v and %v (conflicting types for %v method)",
that cause by go vet.
but this issue failed in cmd/compile.

@findleyr
Copy link
Contributor

@findleyr findleyr commented Jan 19, 2022

This is a different issue from #50658. In the line v2 = v1, v2 is a Doer[T], and v1 is a Doer[int32]. The type checker does not infer that T must be an int32 inside this case.

I don't think this is valid code with the current spec. Shouldn't it be:

	case Doer[int32]:
		var v2 Doer[int32]
		v2 = v1
		fmt.Println("int32!", v1)

?

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jan 20, 2022

Ah, you're right. Sorry for misunderstanding. This is not a bug.

@erifan
Copy link
Contributor

@erifan erifan commented Jan 20, 2022

The type checker does not infer that T must be an int32 inside this case.

Although this is not valid code according to the current spec, but it is clear that the value of T can be inferred under this case statement. So I think it might be more convenient if we make this code valid. Maybe not comparable, but the interface can do it, see https://go.dev/play/p/KqfF-6ElUnR

@findleyr
Copy link
Contributor

@findleyr findleyr commented Jan 20, 2022

it is clear that the value of T can be inferred under this case statement.

While it may be obvious in this case, I think if we were to write down a specification for this feature we'd find that there are many less obvious corner cases, and the resulting behavior may be surprising to users (in short, we'd have to do some sort of unification with types in type lists for type switch cases). My intuition is that it is better to just do the substitution explicitly where necessary, as in writing out var v2 Doer[int32] here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation release-blocker
Projects
None yet
Development

No branches or pull requests

4 participants