建议:go/types:为所有运行时表达式分配非无类型类型 翻译结果:建议:在go/types中,为所有运行时表达式分配非无类型类型,

66bbxpm5  于 4个月前  发布在  Go
关注(0)|答案(5)|浏览(71)

编译器,如cmd/compile和x/tools/go/ssa,更倾向于仅使用真正的类型进行工作,但在以下几种情况下,go/types会将表达式保留为未类型化:
go/src/cmd/compile/internal/noder/helpers.go
第89行 b637211
| | funcidealType(tv syntax.TypeAndValue) types2.Type { |
如果go/types能够为这些上下文提供适当的真正类型,那将是非常方便的,因为它已经在检查未类型化的表达式是否合适。
相关:#47151 提议为表达式的隐式转换类型添加第二个Map。我建议这是避免破坏期望当前未类型化类型的用户(例如,#47243 )的一种合理方法。
/cc @griesemer@findleyr@alandonovan

disbfnqx

disbfnqx1#

许多常量表达式只具有"无类型"的类型。例如,const k = 0。对于这些情况,go/types记录了一个无类型类型。
在其他情况下,常量表达式用于隐含"true"(运行时)类型的上下文中。例如,strings.Repeat("", 1)隐式地将空字符串转换为string类型,将1转换为int类型。在这些情况下,go/types已经将上下文中隐含的转换应用于常量,因此字面量的类型分别记录为string和int。(您可以在types playground中验证这一点。)
(旁注:我模糊地记得很久以前请求过这种行为,但后来后悔了,因为这使得在分析带类型的语法时更容易注意到隐式转换变得更加困难。至少在泛型之前,类型信息很少从上到下流动:只有位移,我记得。)
所以我不确定这个问题具体要求什么更改。

k3bvogb1

k3bvogb12#

我认为更好的方式来表述我的请求是,go/types应该只将"untyped"类型分配给常量表达式。任何非常量表达式都应该有一个已分配的非无类型(untyped)类型。

链接到的代码提到了几个情况,其中go/types将"untyped"类型分配给非常量表达式:
go/src/cmd/compile/internal/noder/helpers.go
第100行到第111行 b637211
| | casetypes2.UntypedInt, types2.UntypedFloat, types2.UntypedComplex: |
| | // 非常量的右移操作的无类型参数,例如 x << 1.0. |
| | // 如果我们有一个常量值,它必须是一个大于等于0的整数。 |
| | iftv.Value!=nil { |
| | s:=constant.ToInt(tv.Value) |
| | assert(s.Kind() ==constant.Int&&constant.Sign(s) >=0) |
| | } |
| | typ=types2.Typ[types2.Uint] |
| | casetypes2.UntypedBool: |
| | typ=types2.Typ[types2.Bool] // "if"或"for"条件中的表达式 |
| | casetypes2.UntypedString: |
| | typ=types2.Typ[types2.String] // "append"或"copy"调用的参数

rm5edbpk

rm5edbpk3#

有趣的是,今天罗伯(Rob)给我发了一条消息,向我介绍了你的工具unconvert。在这条消息的来源中,我发现了#13061,其中你主张将常量保持为未类型化。

vql8enpb

vql8enpb4#

哦,我猜只是在对我的提议进行对冲。

qlfbtfca

qlfbtfca5#

我认为这是可以的,几年前我计划这样做,如果我没记错的话。但我们最终没有这样做,因为(我也不确定了)一些向后兼容性或其他问题。
我们应该再试一次,如果需要的话,引入一个标志来控制行为。

相关问题