]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: report cause for failing const conversions
authorRobert Findley <rfindley@google.com>
Tue, 2 Nov 2021 22:42:51 +0000 (18:42 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 3 Nov 2021 00:07:38 +0000 (00:07 +0000)
This is a port of CL 360795 to go/types. Error messages were adjusted
accordingly, with a TODO to fix the discrepancy.

Change-Id: Ifd7d8248fa11a31fde391021f3c5f1840877892f
Reviewed-on: https://go-review.googlesource.com/c/go/+/360937
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/conversions.go
src/go/types/testdata/spec/conversions.go2

index 9baad98e09cbe64585f7ad64b11afae86866094a..a6f0714ba034205bedc14afd9d3c6e7c5478d3e5 100644 (file)
@@ -49,8 +49,15 @@ func (check *Checker) conversion(x *operand, T Type) {
                // converted.
                ok = under(T).(*TypeParam).underIs(func(u Type) bool {
                        // t is nil if there are no specific type terms
-                       // TODO(gri) add a cause in case of failure
-                       return u != nil && constConvertibleTo(u, nil)
+                       if u == nil {
+                               cause = check.sprintf("%s does not contain specific types", T)
+                               return false
+                       }
+                       if !constConvertibleTo(u, nil) {
+                               cause = check.sprintf("cannot convert %s to %s (in %s)", x, u, T)
+                               return false
+                       }
+                       return true
                })
                x.mode = value // type parameters are not constants
        case x.convertibleTo(check, T, &cause):
index 47b1f07d87235f618108a3344d71610c2768e530..e54403cea9d6820cec2e294bafc80b307a77e856 100644 (file)
@@ -27,6 +27,20 @@ func _[T ~string]() {
        var _ T = 0 // ERROR cannot use .* as T value
 }
 
+// failing const conversions of constants to type parameters report a cause
+func _[
+       T1 any,
+       T2 interface{ m() },
+       T3 ~int | ~float64 | ~bool,
+       T4 ~int | ~string,
+]() {
+       // TODO(rfindley): align the error formatting here with types2.
+       _ = T1(0 /* ERROR cannot convert 0 .* to T1.*T1 does not contain specific types */ )
+       _ = T2(1 /* ERROR cannot convert 1 .* to T2.*T2 does not contain specific types */ )
+       _ = T3(2 /* ERROR cannot convert 2 .* to T3.*cannot convert 2 .* to bool \(in T3\) */ )
+       _ = T4(3.14 /* ERROR cannot convert 3.14 .* to T4.*cannot convert 3.14 .* to int \(in T4\) */ )
+}
+
 // "x is assignable to T"
 // - tested via assignability tests