1
0
mirror of https://github.com/golang/go synced 2024-09-23 15:30:17 -06:00

cmd/compile: treat constants to type parameter conversion as non-constant in Unified IR

Fixes #54307

Change-Id: Idcbdb3b1cf7c7fd147cc079659f29a9b5d17e6e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/421874
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Cuong Manh Le 2022-08-06 20:56:39 +07:00
parent 98f5152368
commit 1519729c6a
4 changed files with 40 additions and 4 deletions

View File

@ -251,3 +251,8 @@ func idealType(tv types2.TypeAndValue) types2.Type {
}
return typ
}
func isTypeParam(t types2.Type) bool {
_, ok := t.(*types2.TypeParam)
return ok
}

View File

@ -2019,6 +2019,7 @@ func (r *reader) expr() (res ir.Node) {
typ := r.typ()
pos := r.pos()
typeWord, srcRType := r.convRTTI(pos)
dstTypeParam := r.Bool()
x := r.expr()
// TODO(mdempsky): Stop constructing expressions of untyped type.
@ -2034,12 +2035,21 @@ func (r *reader) expr() (res ir.Node) {
base.ErrorExit() // harsh, but prevents constructing invalid IR
}
n := ir.NewConvExpr(pos, ir.OCONV, typ, x)
n.TypeWord, n.SrcRType = typeWord, srcRType
ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
ce.TypeWord, ce.SrcRType = typeWord, srcRType
if implicit {
n.SetImplicit(true)
ce.SetImplicit(true)
}
return typecheck.Expr(n)
n := typecheck.Expr(ce)
// spec: "If the type is a type parameter, the constant is converted
// into a non-constant value of the type parameter."
if dstTypeParam && ir.IsConstNode(n) {
// Wrap in an OCONVNOP node to ensure result is non-constant.
n = Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, n.Type(), n))
n.SetTypecheck(1)
}
return n
}
}

View File

@ -1692,6 +1692,7 @@ func (w *writer) expr(expr syntax.Expr) {
w.typ(tv.Type)
w.pos(expr)
w.convRTTI(w.p.typeOf(expr.ArgList[0]), tv.Type)
w.Bool(isTypeParam(tv.Type))
w.expr(expr.ArgList[0])
break
}
@ -1854,6 +1855,7 @@ func (w *writer) implicitConvExpr(pos poser, dst types2.Type, expr syntax.Expr)
w.typ(dst)
w.pos(pos)
w.convRTTI(src, dst)
w.Bool(isTypeParam(dst))
// fallthrough
}
w.expr(expr)

View File

@ -0,0 +1,19 @@
// compile
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package p
func f[Int int, Uint uint]() {
_ = uint(Int(-1))
_ = uint(Uint(0) - 1)
}
func g[String string]() {
_ = String("")[100]
}
var _ = f[int, uint]
var _ = g[string]