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

go/types, types2: better error message when using *interface instead of interface #48312

Closed
zllangct opened this issue Sep 10, 2021 · 4 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@zllangct
Copy link

zllangct commented Sep 10, 2021

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

$ go version
go version devel go1.18-b32209d22d Thu Sep 9 23:18:18 2021 +0000 windows/amd64

What did you do?

package main

import (
	"fmt"
)

type ISetName interface {
	SetName(name string)
}

type Item struct {
	Name string
}


func (i *Item) SetName(name string)  {
	i.Name = name
}

func Hello[T ISetName]()  {
	ins := new(T)
	(ins).SetName("foo")
        fmt.Printf("%+v", ins)
}

func main() {
	Hello[Item]()
}

What did you expect to see?

output: {Name:"foo"}

What did you see instead?

// go version devel go1.18-b32209d22d
output:Item does not satisfy ISetName: wrong method signature
	got  func (*Item).SetName(name string)
	want func (ISetName).SetName(name string)
// go2go playground
output:Item does not satisfy ISetName: wrong method signature
	got  func (*Item).SetName(name string)
	want func (ISetName).SetName(name string)

when method 'SetName' with value receiver is ok, but pointer receiver not

package main

import (
	"fmt"
)

type ISetName interface {
	SetName(name string)
}

type Item struct {
	Name string
}


func (i Item) SetName(name string)  {
	i.Name = name
}

func Hello[T ISetName]()  {
	ins := new(T)
	(ins).SetName("foo")
        fmt.Printf("%+v", ins)
}

func main() {
	Hello[Item]()
}
// go version devel go1.18-b32209d22d
output: error: cannot convert ins (variable of type *T) to ISetName
// go2go playground
output:&{Name:}

It is seem that go2go playroung can work with value receiver method 'SetName', but go version devel go1.18-b32209d22d not.

package main

import (
	"fmt"
)

type ISetName interface {
	SetName(name string)
}

type Item struct {
	Name string
}


func (i Item) SetName(name string)  {
	i.Name = name
}

func Hello[T ISetName]()  {
	ins := new(T)
	(*ins).SetName("foo")
        fmt.Printf("%+v", ins)
}

func main() {
	Hello[Item]()
}
// go version devel go1.18-b32209d22d
output: &{Name:}
@cuonglm
Copy link
Member

cuonglm commented Sep 10, 2021

The error reported is correct, since when you call new(T), this basically a pointer to interface ISetname. If you convert your program to non-generic, and run with go1.17, you will get a clearer error message:

func Hello(T ISetName) {
	ins := &T
	(ins).SetName("foo")
	fmt.Printf("%+v", ins)
}

func main() {
	Hello(&Item{})
}
$ go run t.go
./t.go:21:7: ins.SetName undefined (type *ISetName is pointer to interface, not interface)

Maybe we can make go/types and go/types2 produce a clearer error message.

cc @griesemer @findleyr

@griesemer griesemer changed the title go/types, types2: wrong method signature go/types, types2: better error message when using *interface instead of interface Sep 10, 2021
@griesemer griesemer self-assigned this Sep 10, 2021
@griesemer griesemer added the NeedsFix The path to resolution is known, but the work has not been done. label Sep 10, 2021
@griesemer griesemer added this to the Go1.18 milestone Sep 10, 2021
@griesemer
Copy link
Contributor

Retitled, looking for better error message.

@griesemer griesemer reopened this Sep 10, 2021
@gopherbot
Copy link
Contributor

Change https://golang.org/cl/376914 mentions this issue: go/types, types2: better error message when using *interface instead of interface

@gopherbot
Copy link
Contributor

Change https://golang.org/cl/377375 mentions this issue: go/types, types2: refer to type parameter if so for interface pointer errors

gopherbot pushed a commit that referenced this issue Jan 10, 2022
… errors

Follow-up on comment in CL 376914.

Also:
- add missing check != nil test in assignableTo
- use check.sprintf rather than fmt.Sprintf in missingMethodReason

For #48312.

Change-Id: Ie209b4101a7f2c279e42a59987d0068079c8b69f
Reviewed-on: https://go-review.googlesource.com/c/go/+/377375
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
jproberts pushed a commit to jproberts/go that referenced this issue Jun 21, 2022
…of interface

- detect *interface case and report specific error
- replaced switch with sequence of if's for more clarity
- fixed isInterfacePtr: it applies to all interfaces, incl.
  type parameters
- reviewed/fixed all uses of isInterfacePtr
- adjusted error messages to be consistently of the format
  "type %s is pointer to interface, not interface"

Fixes golang#48312.

Change-Id: Ic3c8cfcf93ad57ecdb60f6a727cce9e1aa4afb5d
Reviewed-on: https://go-review.googlesource.com/c/go/+/376914
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
jproberts pushed a commit to jproberts/go that referenced this issue Jun 21, 2022
… errors

Follow-up on comment in CL 376914.

Also:
- add missing check != nil test in assignableTo
- use check.sprintf rather than fmt.Sprintf in missingMethodReason

For golang#48312.

Change-Id: Ie209b4101a7f2c279e42a59987d0068079c8b69f
Reviewed-on: https://go-review.googlesource.com/c/go/+/377375
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
@golang golang locked and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants