Skip to content

Commit 54ad7f3

Browse files
griesemergopherbot
authored andcommitted
go/types, types2: add test verifying types/values of type parameter "constants"
Fixes #51093. Change-Id: Ida4025a125243159a2107dcc064a0d9addf0a675 Reviewed-on: https://go-review.googlesource.com/c/go/+/443756 Run-TryBot: Robert Griesemer <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Robert Findley <[email protected]> Reviewed-by: Robert Griesemer <[email protected]>
1 parent 4ac413a commit 54ad7f3

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

src/cmd/compile/internal/types2/issues_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -673,3 +673,56 @@ func TestIssue55030(t *testing.T) {
673673
makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
674674
}
675675
}
676+
677+
func TestIssue51093(t *testing.T) {
678+
// Each test stands for a conversion of the form P(val)
679+
// where P is a type parameter with typ as constraint.
680+
// The test ensures that P(val) has the correct type P
681+
// and is not a constant.
682+
var tests = []struct {
683+
typ string
684+
val string
685+
}{
686+
{"bool", "false"},
687+
{"int", "-1"},
688+
{"uint", "1.0"},
689+
{"rune", "'a'"},
690+
{"float64", "3.5"},
691+
{"complex64", "1.25"},
692+
{"string", "\"foo\""},
693+
694+
// some more complex constraints
695+
{"~byte", "1"},
696+
{"~int | ~float64 | complex128", "1"},
697+
{"~uint64 | ~rune", "'X'"},
698+
}
699+
700+
for _, test := range tests {
701+
src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
702+
types := make(map[syntax.Expr]TypeAndValue)
703+
mustTypecheck(t, "p", src, &Info{Types: types})
704+
705+
var n int
706+
for x, tv := range types {
707+
if x, _ := x.(*syntax.CallExpr); x != nil {
708+
// there must be exactly one CallExpr which is the P(val) conversion
709+
n++
710+
tpar, _ := tv.Type.(*TypeParam)
711+
if tpar == nil {
712+
t.Fatalf("%s: got type %s, want type parameter", syntax.String(x), tv.Type)
713+
}
714+
if name := tpar.Obj().Name(); name != "P" {
715+
t.Fatalf("%s: got type parameter name %s, want P", syntax.String(x), name)
716+
}
717+
// P(val) must not be constant
718+
if tv.Value != nil {
719+
t.Errorf("%s: got constant value %s (%s), want no constant", syntax.String(x), tv.Value, tv.Value.String())
720+
}
721+
}
722+
}
723+
724+
if n != 1 {
725+
t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
726+
}
727+
}
728+
}

src/go/types/issues_test.go

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,3 +702,56 @@ func TestIssue55030(t *testing.T) {
702702
makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
703703
}
704704
}
705+
706+
func TestIssue51093(t *testing.T) {
707+
// Each test stands for a conversion of the form P(val)
708+
// where P is a type parameter with typ as constraint.
709+
// The test ensures that P(val) has the correct type P
710+
// and is not a constant.
711+
var tests = []struct {
712+
typ string
713+
val string
714+
}{
715+
{"bool", "false"},
716+
{"int", "-1"},
717+
{"uint", "1.0"},
718+
{"rune", "'a'"},
719+
{"float64", "3.5"},
720+
{"complex64", "1.25"},
721+
{"string", "\"foo\""},
722+
723+
// some more complex constraints
724+
{"~byte", "1"},
725+
{"~int | ~float64 | complex128", "1"},
726+
{"~uint64 | ~rune", "'X'"},
727+
}
728+
729+
for _, test := range tests {
730+
src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
731+
types := make(map[ast.Expr]TypeAndValue)
732+
mustTypecheck(t, "p", src, &Info{Types: types})
733+
734+
var n int
735+
for x, tv := range types {
736+
if x, _ := x.(*ast.CallExpr); x != nil {
737+
// there must be exactly one CallExpr which is the P(val) conversion
738+
n++
739+
tpar, _ := tv.Type.(*TypeParam)
740+
if tpar == nil {
741+
t.Fatalf("%s: got type %s, want type parameter", ExprString(x), tv.Type)
742+
}
743+
if name := tpar.Obj().Name(); name != "P" {
744+
t.Fatalf("%s: got type parameter name %s, want P", ExprString(x), name)
745+
}
746+
// P(val) must not be constant
747+
if tv.Value != nil {
748+
t.Errorf("%s: got constant value %s (%s), want no constant", ExprString(x), tv.Value, tv.Value.String())
749+
}
750+
}
751+
}
752+
753+
if n != 1 {
754+
t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
755+
}
756+
}
757+
}

0 commit comments

Comments
 (0)