You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
cmd/compile/internal/types2: more detailed error messages for generic conversions
- slightly refactor convertibleTo and convertibleToImpl
- provide ability to return a conversion failure cause
- add detailed cause for generic conversions
For #47150.
Change-Id: Ie97d89be0234414ef4df22a6920e18acc944a102
Reviewed-on: https://go-review.googlesource.com/c/go/+/357249
Trust: Robert Griesemer <[email protected]>
Reviewed-by: Robert Findley <[email protected]>
Copy file name to clipboardExpand all lines: src/cmd/compile/internal/types2/testdata/examples/conversions.go2
+11-11
Original file line number
Diff line number
Diff line change
@@ -21,15 +21,15 @@ type Far struct{f float64 }
21
21
func _[X Foo, T Bar](x X) T { return T(x) }
22
22
func _[X Foo|Bar, T Bar](x X) T { return T(x) }
23
23
func _[X Foo, T Foo|Bar](x X) T { return T(x) }
24
-
func _[X Foo, T Far](x X) T { return T(x /* ERROR cannot convert */ ) }
24
+
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\) */ ) }
25
25
26
26
// "x's type and T are unnamed pointer types and their pointer base types
27
27
// have identical underlying types if tags are ignored"
28
28
29
29
func _[X ~*Foo, T ~*Bar](x X) T { return T(x) }
30
30
func _[X ~*Foo|~*Bar, T ~*Bar](x X) T { return T(x) }
31
31
func _[X ~*Foo, T ~*Foo|~*Bar](x X) T { return T(x) }
32
-
func _[X ~*Foo, T ~*Far](x X) T { return T(x /* ERROR cannot convert */ ) }
32
+
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\) */ ) }
33
33
34
34
// Verify that the defined types in constraints are considered for the rule above.
35
35
@@ -60,12 +60,12 @@ func _[X Unsigned, T Float](x X) T { return T(x) }
60
60
func _[X Float, T Float](x X) T { return T(x) }
61
61
62
62
func _[X, T Integer|Unsigned|Float](x X) T { return T(x) }
63
-
func _[X, T Integer|~string](x X) T { return T(x /* ERROR cannot convert */ ) }
63
+
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\) */ ) }
64
64
65
65
// "x's type and T are both complex types"
66
66
67
67
func _[X, T Complex](x X) T { return T(x) }
68
-
func _[X, T Float|Complex](x X) T { return T(x /* ERROR cannot convert */ ) }
68
+
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\) */ ) }
69
69
70
70
// "x is an integer or a slice of bytes or runes and T is a string type"
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 */ ) }
80
80
81
81
func _[T ~string](x []byte) T { return T(x) }
82
82
func _[T ~string](x []rune) T { return T(x) }
83
83
func _[X ~[]byte, T ~string](x X) T { return T(x) }
84
84
func _[X ~[]rune, T ~string](x X) T { return T(x) }
85
85
func _[X Integer|~[]byte|~[]rune, T ~string](x X) T { return T(x) }
86
-
func _[X Integer|~[]byte|~[]rune, T ~*string](x X) T { return T(x /* ERROR cannot convert */ ) }
86
+
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\) */ ) }
87
87
88
88
// "x is a string and T is a slice of bytes or runes"
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\) */ ) }
93
93
94
94
func _[X ~string, T ~[]byte](x X) T { return T(x) }
95
95
func _[X ~string, T ~[]rune](x X) T { return T(x) }
96
96
func _[X ~string, T ~[]byte|~[]rune](x X) T { return T(x) }
97
-
func _[X ~*string, T ~[]byte|~[]rune](x X) T { return T(x /* ERROR cannot convert */ ) }
97
+
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\) */ ) }
98
98
99
99
// package unsafe:
100
100
// "any pointer or value of underlying type uintptr can be converted into a unsafe.Pointer"
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\) */ ) }
107
107
108
108
// "and vice versa"
109
109
110
110
func _[T ~uintptr](x unsafe.Pointer) T { return T(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\n\tcannot convert unsafe\.Pointer \(in X\) to int64 */ ) }
114
114
115
115
// "x is a slice, T is a pointer-to-array type,
116
116
// and the slice and array types have identical element types."
117
117
118
118
func _[X ~[]E, T ~*[10]E, E any](x X) T { return T(x) }
119
-
func _[X ~[]E, T ~[10]E, E any](x X) T { return T(x /* ERROR cannot convert */ ) }
119
+
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\) */ ) }
0 commit comments