aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2022-08-17 15:06:56 -0700
committerRobert Griesemer <gri@google.com>2022-08-18 21:22:06 +0000
commit5fcddf3997a89c1f82935cf65d919b7ef03df2c5 (patch)
tree6ebce46c8d83c335b0af32ebe3497c575bc0b82f /src
parent0eb56ca4688caed10c422f1d2d3b364d75970b8c (diff)
downloadgo-5fcddf3997a89c1f82935cf65d919b7ef03df2c5.tar.xz
go/types: match types2 error msg formatting for conversion errors
This resolves a TODO. Also, it allows go/types and types2 to use identical test files in testdata/spec, a prerequisition for sharing them eventually. For #54511. Change-Id: Ia9d11b15ada237c18b6ce8f72732f70134a1a06f Reviewed-on: https://go-review.googlesource.com/c/go/+/424537 Reviewed-by: Robert Findley <rfindley@google.com> Run-TryBot: Robert Griesemer <gri@google.com> Reviewed-by: Robert Griesemer <gri@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/go/types/conversions.go14
-rw-r--r--src/go/types/testdata/spec/conversions.go31
2 files changed, 22 insertions, 23 deletions
diff --git a/src/go/types/conversions.go b/src/go/types/conversions.go
index 362c8fdbac..3ad94c8eff 100644
--- a/src/go/types/conversions.go
+++ b/src/go/types/conversions.go
@@ -71,23 +71,23 @@ func (check *Checker) conversion(x *operand, T Type) {
}
if !ok {
- // TODO(rfindley): use types2-style error reporting here.
+ var err error_
+ err.code = _InvalidConversion
if compilerErrorMessages {
if cause != "" {
// Add colon at end of line if we have a following cause.
- err := newErrorf(x, _InvalidConversion, "cannot convert %s to type %s:", x, T)
+ err.errorf(x.Pos(), "cannot convert %s to type %s:", x, T)
err.errorf(token.NoPos, cause)
- check.report(err)
} else {
- check.errorf(x, _InvalidConversion, "cannot convert %s to type %s", x, T)
+ err.errorf(x.Pos(), "cannot convert %s to type %s", x, T)
}
} else {
+ err.errorf(x.Pos(), "cannot convert %s to %s", x, T)
if cause != "" {
- check.errorf(x, _InvalidConversion, "cannot convert %s to %s (%s)", x, T, cause)
- } else {
- check.errorf(x, _InvalidConversion, "cannot convert %s to %s", x, T)
+ err.errorf(token.NoPos, cause)
}
}
+ check.report(&err)
x.mode = invalid
return
}
diff --git a/src/go/types/testdata/spec/conversions.go b/src/go/types/testdata/spec/conversions.go
index e54403cea9..fde332f34b 100644
--- a/src/go/types/testdata/spec/conversions.go
+++ b/src/go/types/testdata/spec/conversions.go
@@ -34,11 +34,10 @@ func _[
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\) */ )
+ _ = T1(0 /* ERROR cannot convert 0 .* to T1\n\tT1 does not contain specific types */ )
+ _ = T2(1 /* ERROR cannot convert 1 .* to T2\n\tT2 does not contain specific types */ )
+ _ = T3(2 /* ERROR cannot convert 2 .* to T3\n\tcannot convert 2 .* to bool \(in T3\) */ )
+ _ = T4(3.14 /* ERROR cannot convert 3.14 .* to T4\n\tcannot convert 3.14 .* to int \(in T4\) */ )
}
// "x is assignable to T"
@@ -56,7 +55,7 @@ type Far struct{f float64 }
func _[X Foo, T Bar](x X) T { return T(x) }
func _[X Foo|Bar, T Bar](x X) T { return T(x) }
func _[X Foo, T Foo|Bar](x X) T { return T(x) }
-func _[X Foo, T Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to T.*cannot convert Foo \(in X\) to Far \(in T\) */ ) }
+func _[X Foo, T Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to T\n\tcannot convert Foo \(in X\) to Far \(in T\) */ ) }
// "x's type and T are unnamed pointer types and their pointer base types
// have identical underlying types if tags are ignored"
@@ -64,7 +63,7 @@ func _[X Foo, T Far](x X) T { return T(x /* ERROR cannot convert x \(variable of
func _[X ~*Foo, T ~*Bar](x X) T { return T(x) }
func _[X ~*Foo|~*Bar, T ~*Bar](x X) T { return T(x) }
func _[X ~*Foo, T ~*Foo|~*Bar](x X) T { return T(x) }
-func _[X ~*Foo, T ~*Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to T.*cannot convert \*Foo \(in X\) to \*Far \(in T\) */ ) }
+func _[X ~*Foo, T ~*Far](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to T\n\tcannot convert \*Foo \(in X\) to \*Far \(in T\) */ ) }
// Verify that the defined types in constraints are considered for the rule above.
@@ -95,12 +94,12 @@ func _[X Unsigned, T Float](x X) T { return T(x) }
func _[X Float, T Float](x X) T { return T(x) }
func _[X, T Integer|Unsigned|Float](x X) T { return T(x) }
-func _[X, T Integer|~string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~string\) to T.*cannot convert string \(in X\) to int \(in T\) */ ) }
+func _[X, T Integer|~string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~string\) to T\n\tcannot convert string \(in X\) to int \(in T\) */ ) }
// "x's type and T are both complex types"
func _[X, T Complex](x X) T { return T(x) }
-func _[X, T Float|Complex](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Float\|Complex\) to T.*cannot convert float32 \(in X\) to complex64 \(in T\) */ ) }
+func _[X, T Float|Complex](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Float\|Complex\) to T\n\tcannot convert float32 \(in X\) to complex64 \(in T\) */ ) }
// "x is an integer or a slice of bytes or runes and T is a string type"
@@ -111,25 +110,25 @@ func _[T ~string](x int) T { return T(x) }
func _[T ~string](x myInt) T { return T(x) }
func _[X Integer](x X) string { return string(x) }
func _[X Integer](x X) myString { return myString(x) }
-func _[X Integer](x X) *string { return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to \*string.*cannot convert int \(in X\) to \*string */ ) }
+func _[X Integer](x X) *string { return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to \*string\n\tcannot convert int \(in X\) to \*string */ ) }
func _[T ~string](x []byte) T { return T(x) }
func _[T ~string](x []rune) T { return T(x) }
func _[X ~[]byte, T ~string](x X) T { return T(x) }
func _[X ~[]rune, T ~string](x X) T { return T(x) }
func _[X Integer|~[]byte|~[]rune, T ~string](x X) T { return T(x) }
-func _[X Integer|~[]byte|~[]rune, T ~*string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~\[\]byte\|~\[\]rune\) to T.*cannot convert int \(in X\) to \*string \(in T\) */ ) }
+func _[X Integer|~[]byte|~[]rune, T ~*string](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer\|~\[\]byte\|~\[\]rune\) to T\n\tcannot convert int \(in X\) to \*string \(in T\) */ ) }
// "x is a string and T is a slice of bytes or runes"
func _[T ~[]byte](x string) T { return T(x) }
func _[T ~[]rune](x string) T { return T(x) }
-func _[T ~[]rune](x *string) T { return T(x /* ERROR cannot convert x \(variable of type \*string\) to T.*cannot convert \*string to \[\]rune \(in T\) */ ) }
+func _[T ~[]rune](x *string) T { return T(x /* ERROR cannot convert x \(variable of type \*string\) to T\n\tcannot convert \*string to \[\]rune \(in T\) */ ) }
func _[X ~string, T ~[]byte](x X) T { return T(x) }
func _[X ~string, T ~[]rune](x X) T { return T(x) }
func _[X ~string, T ~[]byte|~[]rune](x X) T { return T(x) }
-func _[X ~*string, T ~[]byte|~[]rune](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to T.*cannot convert \*string \(in X\) to \[\]byte \(in T\) */ ) }
+func _[X ~*string, T ~[]byte|~[]rune](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to T\n\tcannot convert \*string \(in X\) to \[\]byte \(in T\) */ ) }
// package unsafe:
// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
@@ -138,20 +137,20 @@ type myUintptr uintptr
func _[X ~uintptr](x X) unsafe.Pointer { return unsafe.Pointer(x) }
func _[T unsafe.Pointer](x myUintptr) T { return T(x) }
-func _[T unsafe.Pointer](x int64) T { return T(x /* ERROR cannot convert x \(variable of type int64\) to T.*cannot convert int64 to unsafe\.Pointer \(in T\) */ ) }
+func _[T unsafe.Pointer](x int64) T { return T(x /* ERROR cannot convert x \(variable of type int64\) to T\n\tcannot convert int64 to unsafe\.Pointer \(in T\) */ ) }
// "and vice versa"
func _[T ~uintptr](x unsafe.Pointer) T { return T(x) }
func _[X unsafe.Pointer](x X) uintptr { return uintptr(x) }
func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) }
-func _[X unsafe.Pointer](x X) int64 { return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to int64.*cannot convert unsafe\.Pointer \(in X\) to int64 */ ) }
+func _[X unsafe.Pointer](x X) int64 { return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to int64\n\tcannot convert unsafe\.Pointer \(in X\) to int64 */ ) }
// "x is a slice, T is a pointer-to-array type,
// and the slice and array types have identical element types."
func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) }
-func _[X ~[]E, T ~[10]E, E any](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\[\]E\) to T.*cannot convert \[\]E \(in X\) to \[10\]E \(in T\) */ ) }
+func _[X ~[]E, T ~[10]E, E any](x X) T { return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\[\]E\) to T\n\tcannot convert \[\]E \(in X\) to \[10\]E \(in T\) */ ) }
// ----------------------------------------------------------------------------
// The following declarations can be replaced by the exported types of the