Skip to content

Commit

Permalink
cmd/compile: treat constants to type parameter conversion as non-cons…
Browse files Browse the repository at this point in the history
…tant in Unified IR

Fixes golang#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>
  • Loading branch information
cuonglm authored and jproberts committed Aug 10, 2022
1 parent 73a2279 commit 2994661
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/cmd/compile/internal/noder/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
18 changes: 14 additions & 4 deletions src/cmd/compile/internal/noder/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/noder/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions test/fixedbugs/issue54307.go
Original file line number Diff line number Diff line change
@@ -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]

0 comments on commit 2994661

Please sign in to comment.