go `cmd/compile: 涉及别名类型的错误应使用别名名称`

41zrol4v  于 2个月前  发布在  Go
关注(0)|答案(8)|浏览(95)

https://golang.org/cl/63277 中,@ianlancetaylor 指出:
现在如果我编译

package p

type myByte = byte
var _ myByte = "uc"

我得到
foo.go:4:16: cannot use "uc" (type string) as type byte in assignment
可以认为这是错误的。例如,gccgo 打印
foo.go:4:5: error: incompatible type in initialization (cannot use type string as type myByte)
如果我们首先修复编译器在错误消息中使用别名名称,我认为它应该这样做,那么也许我们可以在保留良好错误消息的同时应用这个更改。
具体来说:如果编译器报告一个涉及别名的类型错误,它应该使用类型的别名而不是底层/规范名称。
这将允许我们在 C 类型( #13467 )的更大子集中使用类型别名,而不会为不匹配的类型产生过于复杂的错误消息。

sdnqo3pr

sdnqo3pr1#

CC @griesemer@mdempsky

js81xvg6

js81xvg62#

随机驾驶思考;不要只使用别名名称,而是使用别名名称和底层定义类型的组合。以你的例子为例:

foo.go:4:5: error: incompatible type in initialization (cannot use type string as type myByte (-> byte))

🚲 -欢迎在格式上脱落。
原因在于,错误信息随后变得清晰,即 myByte 是别名( type myByte = byte )而不是定义类型( type myByte byte )。

ndh0cuux

ndh0cuux3#

这是一个已知的cmd/compile(和go/types)的限制,但我认为我们没有提交一个问题,所以感谢!
在cmd/compile中,我们实现

type myByte = byte

的方式是将myByte简单地定义为byte的OTYPE gc.Node。然而,相应的types.Type并不知道“myByte”这个名字。
编译器中有一个先例,即uint8byte以及int32rune(实际上也是别名)实际上被表示为单独的types.Type对象,然后在编译器的几个地方我们对这两个特殊情况进行了特殊处理(例如,类型身份的eqtype)。
也许最简单的修复方法是将这些特殊情况泛化为任何类型的类型别名。

t1rydlwq

t1rydlwq4#

另一个(可能明显的)支持@bcmills提议的观察是与文档的一致性:

package playground

import (
	"github.com/myitcv/playground/internal/a"
)

type T = a.S

func Hello(s T) {
}

func Fail() {
	Hello(5)
}

在编译时出现错误信息:

# github.com/myitcv/playground
./playground.go:13:8: cannot use 5 (type int) as type a.S in argument to Hello

但是 godoc 是:

func Hello(s T)
nfg76nw0

nfg76nw05#

https://golang.org/cl/98476提到了这个问题:cmd/compile: prevent detection of wrong duplicates

n9vozmp4

n9vozmp46#

我对这个问题很感兴趣,所以我在思考。

bxjv4tth

bxjv4tth7#

我同意这是一个"锦上添花"的功能,但我认为它并不是特别重要的优先事项。我也认为在一般情况下正确实现它是相当微妙的(需要完全理解编译器中的类型表示)。

相关问题