mirror of
https://github.com/golang/go.git
synced 2025-05-05 15:43:04 +00: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:
parent
98f5152368
commit
1519729c6a
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
19
test/fixedbugs/issue54307.go
Normal file
19
test/fixedbugs/issue54307.go
Normal 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]
|
Loading…
x
Reference in New Issue
Block a user