mirror of
https://github.com/golang/go
synced 2024-09-04 23:44:16 +00:00
[dev.typeparams] cmd/compile: handle ++/-- in noder2 for operands with generic type
types2 will have already proved the expression's type is compatible, so just assign the one const to have the same type as the operand. Fixes #47258. Change-Id: If0844e6bf6d0a5e6b11453b87df71353863ccc5d Reviewed-on: https://go-review.googlesource.com/c/go/+/336009 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com>
This commit is contained in:
parent
f19e49e7b1
commit
dcc8350ad3
|
@ -337,5 +337,15 @@ var one = constant.MakeInt64(1)
|
||||||
|
|
||||||
func IncDec(pos src.XPos, op ir.Op, x ir.Node) *ir.AssignOpStmt {
|
func IncDec(pos src.XPos, op ir.Op, x ir.Node) *ir.AssignOpStmt {
|
||||||
assert(x.Type() != nil)
|
assert(x.Type() != nil)
|
||||||
return ir.NewAssignOpStmt(pos, op, x, typecheck.DefaultLit(ir.NewBasicLit(pos, one), x.Type()))
|
bl := ir.NewBasicLit(pos, one)
|
||||||
|
if x.Type().HasTParam() {
|
||||||
|
// If the operand is generic, then types2 will have proved it must be
|
||||||
|
// a type that fits with increment/decrement, so just set the type of
|
||||||
|
// "one" to n.Type(). This works even for types that are eventually
|
||||||
|
// float or complex.
|
||||||
|
typed(x.Type(), bl)
|
||||||
|
} else {
|
||||||
|
bl = typecheck.DefaultLit(bl, x.Type())
|
||||||
|
}
|
||||||
|
return ir.NewAssignOpStmt(pos, op, x, bl)
|
||||||
}
|
}
|
||||||
|
|
32
test/typeparam/issue47258.go
Normal file
32
test/typeparam/issue47258.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// run -gcflags=-G=3
|
||||||
|
|
||||||
|
// Copyright 2021 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 main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Numeric interface {
|
||||||
|
int32|int64|float64|complex64
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:noline
|
||||||
|
func inc[T Numeric](x T) T {
|
||||||
|
x++
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
func main() {
|
||||||
|
if got, want := inc(int32(5)), int32(6); got != want {
|
||||||
|
panic(fmt.Sprintf("got %d, want %d", got, want))
|
||||||
|
}
|
||||||
|
if got, want := inc(float64(5)), float64(6.0); got != want {
|
||||||
|
panic(fmt.Sprintf("got %d, want %d", got, want))
|
||||||
|
}
|
||||||
|
if got, want := inc(complex64(5)), complex64(6.0); got != want {
|
||||||
|
panic(fmt.Sprintf("got %d, want %d", got, want))
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue