]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: add test verifying types/values of type parameter "constants"
authorRobert Griesemer <gri@golang.org>
Tue, 18 Oct 2022 18:12:48 +0000 (11:12 -0700)
committerGopher Robot <gobot@golang.org>
Tue, 18 Oct 2022 20:45:51 +0000 (20:45 +0000)
Fixes #51093.

Change-Id: Ida4025a125243159a2107dcc064a0d9addf0a675
Reviewed-on: https://go-review.googlesource.com/c/go/+/443756
Run-TryBot: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
src/cmd/compile/internal/types2/issues_test.go
src/go/types/issues_test.go

index efd27bf7ccc979da8bd27e1645dce90ce0f34842..afce7e27159d27f3d4140de2c10ef8eebdb04327 100644 (file)
@@ -673,3 +673,56 @@ func TestIssue55030(t *testing.T) {
                makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
        }
 }
+
+func TestIssue51093(t *testing.T) {
+       // Each test stands for a conversion of the form P(val)
+       // where P is a type parameter with typ as constraint.
+       // The test ensures that P(val) has the correct type P
+       // and is not a constant.
+       var tests = []struct {
+               typ string
+               val string
+       }{
+               {"bool", "false"},
+               {"int", "-1"},
+               {"uint", "1.0"},
+               {"rune", "'a'"},
+               {"float64", "3.5"},
+               {"complex64", "1.25"},
+               {"string", "\"foo\""},
+
+               // some more complex constraints
+               {"~byte", "1"},
+               {"~int | ~float64 | complex128", "1"},
+               {"~uint64 | ~rune", "'X'"},
+       }
+
+       for _, test := range tests {
+               src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
+               types := make(map[syntax.Expr]TypeAndValue)
+               mustTypecheck(t, "p", src, &Info{Types: types})
+
+               var n int
+               for x, tv := range types {
+                       if x, _ := x.(*syntax.CallExpr); x != nil {
+                               // there must be exactly one CallExpr which is the P(val) conversion
+                               n++
+                               tpar, _ := tv.Type.(*TypeParam)
+                               if tpar == nil {
+                                       t.Fatalf("%s: got type %s, want type parameter", syntax.String(x), tv.Type)
+                               }
+                               if name := tpar.Obj().Name(); name != "P" {
+                                       t.Fatalf("%s: got type parameter name %s, want P", syntax.String(x), name)
+                               }
+                               // P(val) must not be constant
+                               if tv.Value != nil {
+                                       t.Errorf("%s: got constant value %s (%s), want no constant", syntax.String(x), tv.Value, tv.Value.String())
+                               }
+                       }
+               }
+
+               if n != 1 {
+                       t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
+               }
+       }
+}
index de8e0ad5f1a3594b68227f7cebd902dc1ea158a3..b96f68d57543c796cd03d9b76cdbeaa6c38b12fd 100644 (file)
@@ -702,3 +702,56 @@ func TestIssue55030(t *testing.T) {
                makeSig(NewTypeParam(P, NewInterfaceType(nil, []Type{u})))
        }
 }
+
+func TestIssue51093(t *testing.T) {
+       // Each test stands for a conversion of the form P(val)
+       // where P is a type parameter with typ as constraint.
+       // The test ensures that P(val) has the correct type P
+       // and is not a constant.
+       var tests = []struct {
+               typ string
+               val string
+       }{
+               {"bool", "false"},
+               {"int", "-1"},
+               {"uint", "1.0"},
+               {"rune", "'a'"},
+               {"float64", "3.5"},
+               {"complex64", "1.25"},
+               {"string", "\"foo\""},
+
+               // some more complex constraints
+               {"~byte", "1"},
+               {"~int | ~float64 | complex128", "1"},
+               {"~uint64 | ~rune", "'X'"},
+       }
+
+       for _, test := range tests {
+               src := fmt.Sprintf("package p; func _[P %s]() { _ = P(%s) }", test.typ, test.val)
+               types := make(map[ast.Expr]TypeAndValue)
+               mustTypecheck(t, "p", src, &Info{Types: types})
+
+               var n int
+               for x, tv := range types {
+                       if x, _ := x.(*ast.CallExpr); x != nil {
+                               // there must be exactly one CallExpr which is the P(val) conversion
+                               n++
+                               tpar, _ := tv.Type.(*TypeParam)
+                               if tpar == nil {
+                                       t.Fatalf("%s: got type %s, want type parameter", ExprString(x), tv.Type)
+                               }
+                               if name := tpar.Obj().Name(); name != "P" {
+                                       t.Fatalf("%s: got type parameter name %s, want P", ExprString(x), name)
+                               }
+                               // P(val) must not be constant
+                               if tv.Value != nil {
+                                       t.Errorf("%s: got constant value %s (%s), want no constant", ExprString(x), tv.Value, tv.Value.String())
+                               }
+                       }
+               }
+
+               if n != 1 {
+                       t.Fatalf("%s: got %d CallExpr nodes; want 1", src, 1)
+               }
+       }
+}