[go] go/types, types2: fix string to type parameter conversions

28 views
Skip to first unread message

Robert Griesemer (Gerrit)

unread,
Feb 27, 2022, 9:23:22 PM2/27/22
to goph...@pubsubhelper.golang.org, Robert Griesemer, golang-co...@googlegroups.com

Robert Griesemer has uploaded this change for review.

View Change

go/types, types2: fix string to type parameter conversions

Converting an untyped constant to a type parameter results
in a non-constant value; but the constant must still be
representable by all specific types of the type parameter.

Adjust the special handling for constant-to-type parameter
conversions to also include string-to-[]byte and []rune
conversions, which are handled separately for conversions
to types that are not type parameters because those are not
constant conversions in non-generic code.

Fixes #51386.

Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
---
M src/cmd/compile/internal/types2/conversions.go
A src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
M src/go/types/conversions.go
A src/go/types/testdata/fixedbugs/issue51386.go2
4 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
index 7fe1d50..f3e95fd 100644
--- a/src/cmd/compile/internal/types2/conversions.go
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -19,8 +19,10 @@

constConvertibleTo := func(T Type, val *constant.Value) bool {
switch t, _ := under(T).(*Basic); {
+ case isString(x.typ) && isBytesOrRunes(T):
+ return true
case t == nil:
- // nothing to do
+ return false // exit early: T is not a basic type
case representableConst(x.val, check, t, val):
return true
case isInteger(x.typ) && isString(t):
diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
new file mode 100644
index 0000000..ef622392
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
@@ -0,0 +1,17 @@
+// 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
+
+type myString string
+
+func _[P ~string | ~[]byte | ~[]rune]() {
+ _ = P("")
+ const s myString = ""
+ _ = P(s)
+}
+
+func _[P myString]() {
+ _ = P("")
+}
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index 8474135..058adab 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -18,8 +18,10 @@

constConvertibleTo := func(T Type, val *constant.Value) bool {
switch t, _ := under(T).(*Basic); {
+ case isString(x.typ) && isBytesOrRunes(T):
+ return true
case t == nil:
- // nothing to do
+ return false // exit early: T is not a basic type
case representableConst(x.val, check, t, val):
return true
case isInteger(x.typ) && isString(t):
diff --git a/src/go/types/testdata/fixedbugs/issue51386.go2 b/src/go/types/testdata/fixedbugs/issue51386.go2
new file mode 100644
index 0000000..ef622392
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue51386.go2
@@ -0,0 +1,17 @@
+// 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
+
+type myString string
+
+func _[P ~string | ~[]byte | ~[]rune]() {
+ _ = P("")
+ const s myString = ""
+ _ = P(s)
+}
+
+func _[P myString]() {
+ _ = P("")
+}

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 1
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-MessageType: newchange

Robert Findley (Gerrit)

unread,
Feb 28, 2022, 9:58:10 AM2/28/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

Attention is currently required from: Robert Griesemer.

Patch set 1:Code-Review +2

View Change

2 comments:

  • File src/go/types/conversions.go:

    • Patch Set #1, Line 21:

      		case isString(x.typ) && isBytesOrRunes(T):
      return true

      This looks out of place here, since the rest of this function is about representability.

      But I agree it fixes the bug.

    • Patch Set #1, Line 58: if !constConvertibleTo(u, nil)

      I don't quite recall why we wouldn't just call x.convertibleTo here, based on the description above. Could use some explanation.

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 1
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-Attention: Robert Griesemer <g...@golang.org>
Gerrit-Comment-Date: Mon, 28 Feb 2022 14:58:06 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Gerrit-MessageType: comment

Robert Griesemer (Gerrit)

unread,
Feb 28, 2022, 1:13:52 PM2/28/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, Robert Findley, Gopher Robot, golang-co...@googlegroups.com

View Change

2 comments:

  • File src/go/types/conversions.go:

    • This looks out of place here, since the rest of this function is about representability. […]

      Agreed. But it was the easiest change to make. I'll see if I can make this clearer.

      (Also note that this case is not reachable when we convert to a constant type (byte and rune slices are not constant types.)

    • I don't quite recall why we wouldn't just call x.convertibleTo here, based on the description above. […]

      The explanation is on line 47ff. Without that requirement - which is written down in the spec and which we need because upon monomorphization we have a single type - we could simply drop this entire case in the switch and the code would type-check.

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 1
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-Comment-Date: Mon, 28 Feb 2022 18:13:47 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Comment-In-Reply-To: Robert Findley <rfin...@google.com>
Gerrit-MessageType: comment

Robert Griesemer (Gerrit)

unread,
Feb 28, 2022, 1:20:34 PM2/28/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, golang-co...@googlegroups.com

Robert Griesemer uploaded patch set #2 to this change.

View Change

go/types, types2: fix string to type parameter conversions

Converting an untyped constant to a type parameter results
in a non-constant value; but the constant must still be
representable by all specific types of the type parameter.

Adjust the special handling for constant-to-type parameter
conversions to also include string-to-[]byte and []rune
conversions, which are handled separately for conversions
to types that are not type parameters because those are not
constant conversions in non-generic code.

Fixes #51386.

Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
---
M src/cmd/compile/internal/types2/conversions.go
A src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
M src/go/types/conversions.go
A src/go/types/testdata/fixedbugs/issue51386.go2
4 files changed, 63 insertions(+), 2 deletions(-)

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 2
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-MessageType: newpatchset

Robert Griesemer (Gerrit)

unread,
Feb 28, 2022, 1:20:56 PM2/28/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, Robert Findley, Gopher Robot, golang-co...@googlegroups.com

View Change

1 comment:

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 2
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-Comment-Date: Mon, 28 Feb 2022 18:20:52 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: No
Gerrit-MessageType: comment

Robert Findley (Gerrit)

unread,
Feb 28, 2022, 2:05:43 PM2/28/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, Gopher Robot, golang-co...@googlegroups.com

Attention is currently required from: Robert Griesemer.

Patch set 2:Code-Review +2

View Change

2 comments:

  • File src/go/types/conversions.go:

    • (Also note that this case is not reachable when we convert to a constant type (byte and rune slices are not constant types.)

      Yep, I observed that, but it looked fragile. New patchset looks better to me.

    • The explanation is on line 47ff. […]

      Ack, thanks for the additional explanation.

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 2
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-Attention: Robert Griesemer <g...@golang.org>
Gerrit-Comment-Date: Mon, 28 Feb 2022 19:05:40 +0000
Gerrit-HasComments: Yes
Gerrit-Has-Labels: Yes
Comment-In-Reply-To: Robert Findley <rfin...@google.com>
Comment-In-Reply-To: Robert Griesemer <g...@golang.org>
Gerrit-MessageType: comment

Robert Griesemer (Gerrit)

unread,
Feb 28, 2022, 4:50:58 PM2/28/22
to Robert Griesemer, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, Gopher Robot, Robert Findley, golang-co...@googlegroups.com

Robert Griesemer submitted this change.

View Change



2 is the latest approved patch-set.
No files were changed between the latest approved patch-set and the submitted one.

Approvals: Robert Findley: Looks good to me, approved Robert Griesemer: Trusted
go/types, types2: fix string to type parameter conversions

Converting an untyped constant to a type parameter results
in a non-constant value; but the constant must still be
representable by all specific types of the type parameter.

Adjust the special handling for constant-to-type parameter
conversions to also include string-to-[]byte and []rune
conversions, which are handled separately for conversions
to types that are not type parameters because those are not
constant conversions in non-generic code.

Fixes #51386.

Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Reviewed-on: https://go-review.googlesource.com/c/go/+/388254
Trust: Robert Griesemer <g...@golang.org>
Reviewed-by: Robert Findley <rfin...@google.com>

---
M src/cmd/compile/internal/types2/conversions.go
A src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
M src/go/types/conversions.go
A src/go/types/testdata/fixedbugs/issue51386.go2
4 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/src/cmd/compile/internal/types2/conversions.go b/src/cmd/compile/internal/types2/conversions.go
index 7fe1d50..08b3cbf 100644
--- a/src/cmd/compile/internal/types2/conversions.go
+++ b/src/cmd/compile/internal/types2/conversions.go
@@ -49,11 +49,14 @@
// have specific types, constant x cannot be
// converted.
ok = T.(*TypeParam).underIs(func(u Type) bool {
- // t is nil if there are no specific type terms
+ // u is nil if there are no specific type terms
if u == nil {
cause = check.sprintf("%s does not contain specific types", T)
return false
}
+ if isString(x.typ) && isBytesOrRunes(u) {
+ return true
+ }
if !constConvertibleTo(u, nil) {
cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
return false

diff --git a/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2 b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
new file mode 100644
index 0000000..ef622392
--- /dev/null
+++ b/src/cmd/compile/internal/types2/testdata/fixedbugs/issue51386.go2
@@ -0,0 +1,17 @@
+// 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
+
+type myString string
+
+func _[P ~string | ~[]byte | ~[]rune]() {
+ _ = P("")
+ const s myString = ""
+ _ = P(s)
+}
+
+func _[P myString]() {
+ _ = P("")
+}
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index 8474135..c5a69cd 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -48,11 +48,14 @@
// have specific types, constant x cannot be
// converted.
ok = T.(*TypeParam).underIs(func(u Type) bool {
- // t is nil if there are no specific type terms
+ // u is nil if there are no specific type terms
if u == nil {
cause = check.sprintf("%s does not contain specific types", T)
return false
}
+ if isString(x.typ) && isBytesOrRunes(u) {
+ return true
+ }
if !constConvertibleTo(u, nil) {
cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
return false

diff --git a/src/go/types/testdata/fixedbugs/issue51386.go2 b/src/go/types/testdata/fixedbugs/issue51386.go2
new file mode 100644
index 0000000..ef622392
--- /dev/null
+++ b/src/go/types/testdata/fixedbugs/issue51386.go2
@@ -0,0 +1,17 @@
+// 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
+
+type myString string
+
+func _[P ~string | ~[]byte | ~[]rune]() {
+ _ = P("")
+ const s myString = ""
+ _ = P(s)
+}
+
+func _[P myString]() {
+ _ = P("")
+}

To view, visit change 388254. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I15e5a0fd281efd15af387280cd3dee320a1ac5e1
Gerrit-Change-Number: 388254
Gerrit-PatchSet: 4
Gerrit-Owner: Robert Griesemer <g...@golang.org>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Robert Findley <rfin...@google.com>
Gerrit-Reviewer: Robert Griesemer <g...@golang.org>
Gerrit-MessageType: merged
Reply all
Reply to author
Forward
0 new messages