Skip to content

Commit 7997e5f

Browse files
griesemergopherbot
authored andcommitted
cmd/compile: use "cannot use %s as %s value in %s: %s" error message
This is close to what the compiler used to say, except now we say "as T value" rather than "as type T" which is closer to the truth (we cannot use a value as a type, after all). Also, place the primary error and the explanation (cause) on a single line. Make respective (single line) adjustment to the matching "cannot convert" error. Adjust various tests. For #55326. Change-Id: Ib646cf906b11f4129b7ed0c38cf16471f9266b88 Reviewed-on: https://go-review.googlesource.com/c/go/+/436176 Reviewed-by: Robert Griesemer <[email protected]> Run-TryBot: Robert Griesemer <[email protected]> Auto-Submit: Robert Griesemer <[email protected]> Reviewed-by: Robert Findley <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 435652b commit 7997e5f

File tree

12 files changed

+46
-71
lines changed

12 files changed

+46
-71
lines changed

src/cmd/compile/internal/types2/assignments.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,12 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
8585
return
8686
}
8787

88-
reason := ""
89-
if ok, code := x.assignableTo(check, T, &reason); !ok {
90-
if check.conf.CompilerErrorMessages {
91-
if reason != "" {
92-
check.errorf(x, code, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
93-
} else {
94-
check.errorf(x, code, "cannot use %s as type %s in %s", x, T, context)
95-
}
88+
cause := ""
89+
if ok, code := x.assignableTo(check, T, &cause); !ok {
90+
if cause != "" {
91+
check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
9692
} else {
97-
if reason != "" {
98-
check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason)
99-
} else {
100-
check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
101-
}
93+
check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
10294
}
10395
x.mode = invalid
10496
}

src/cmd/compile/internal/types2/conversions.go

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,11 @@ func (check *Checker) conversion(x *operand, T Type) {
7070
}
7171

7272
if !ok {
73-
var err error_
74-
err.code = _InvalidConversion
7573
if cause != "" {
76-
err.errorf(x, "cannot convert %s to type %s:", x, T)
77-
err.errorf(nopos, cause)
74+
check.errorf(x, _InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
7875
} else {
79-
err.errorf(x, "cannot convert %s to type %s", x, T)
76+
check.errorf(x, _InvalidConversion, "cannot convert %s to type %s", x, T)
8077
}
81-
check.report(&err)
8278
x.mode = invalid
8379
return
8480
}

src/go/types/assignments.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,12 @@ func (check *Checker) assignment(x *operand, T Type, context string) {
8484
return
8585
}
8686

87-
reason := ""
88-
if ok, code := x.assignableTo(check, T, &reason); !ok {
89-
if compilerErrorMessages {
90-
if reason != "" {
91-
check.errorf(x, code, "cannot use %s as type %s in %s:\n\t%s", x, T, context, reason)
92-
} else {
93-
check.errorf(x, code, "cannot use %s as type %s in %s", x, T, context)
94-
}
87+
cause := ""
88+
if ok, code := x.assignableTo(check, T, &cause); !ok {
89+
if cause != "" {
90+
check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, cause)
9591
} else {
96-
if reason != "" {
97-
check.errorf(x, code, "cannot use %s as %s value in %s: %s", x, T, context, reason)
98-
} else {
99-
check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
100-
}
92+
check.errorf(x, code, "cannot use %s as %s value in %s", x, T, context)
10193
}
10294
x.mode = invalid
10395
}

src/go/types/conversions.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ package types
88

99
import (
1010
"go/constant"
11-
"go/token"
1211
"unicode"
1312
)
1413

@@ -71,15 +70,11 @@ func (check *Checker) conversion(x *operand, T Type) {
7170
}
7271

7372
if !ok {
74-
var err error_
75-
err.code = _InvalidConversion
7673
if cause != "" {
77-
err.errorf(x.Pos(), "cannot convert %s to type %s:", x, T)
78-
err.errorf(token.NoPos, cause)
74+
check.errorf(x, _InvalidConversion, "cannot convert %s to type %s: %s", x, T, cause)
7975
} else {
80-
err.errorf(x.Pos(), "cannot convert %s to type %s", x, T)
76+
check.errorf(x, _InvalidConversion, "cannot convert %s to type %s", x, T)
8177
}
82-
check.report(&err)
8378
x.mode = invalid
8479
return
8580
}

src/internal/types/testdata/spec/conversions.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ func _[
3434
T3 ~int | ~float64 | ~bool,
3535
T4 ~int | ~string,
3636
]() {
37-
_ = T1(0 /* ERROR cannot convert 0 .* to type T1:\n\tT1 does not contain specific types */)
38-
_ = T2(1 /* ERROR cannot convert 1 .* to type T2:\n\tT2 does not contain specific types */)
39-
_ = T3(2 /* ERROR cannot convert 2 .* to type T3:\n\tcannot convert 2 .* to type bool \(in T3\) */)
40-
_ = T4(3.14 /* ERROR cannot convert 3.14 .* to type T4:\n\tcannot convert 3.14 .* to type int \(in T4\) */)
37+
_ = T1(0 /* ERROR cannot convert 0 .* to type T1: T1 does not contain specific types */)
38+
_ = T2(1 /* ERROR cannot convert 1 .* to type T2: T2 does not contain specific types */)
39+
_ = T3(2 /* ERROR cannot convert 2 .* to type T3: cannot convert 2 .* to type bool \(in T3\) */)
40+
_ = T4(3.14 /* ERROR cannot convert 3.14 .* to type T4: cannot convert 3.14 .* to type int \(in T4\) */)
4141
}
4242

4343
// "x is assignable to T"
@@ -66,7 +66,7 @@ func _[X Foo, T Bar](x X) T { return T(x) }
6666
func _[X Foo | Bar, T Bar](x X) T { return T(x) }
6767
func _[X Foo, T Foo | Bar](x X) T { return T(x) }
6868
func _[X Foo, T Far](x X) T {
69-
return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to type T:\n\tcannot convert Foo \(in X\) to type Far \(in T\) */)
69+
return T(x /* ERROR cannot convert x \(variable of type X constrained by Foo\) to type T: cannot convert Foo \(in X\) to type Far \(in T\) */)
7070
}
7171

7272
// "x's type and T are unnamed pointer types and their pointer base types
@@ -76,7 +76,7 @@ func _[X ~*Foo, T ~*Bar](x X) T { return T(x) }
7676
func _[X ~*Foo | ~*Bar, T ~*Bar](x X) T { return T(x) }
7777
func _[X ~*Foo, T ~*Foo | ~*Bar](x X) T { return T(x) }
7878
func _[X ~*Foo, T ~*Far](x X) T {
79-
return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to type T:\n\tcannot convert \*Foo \(in X\) to type \*Far \(in T\) */)
79+
return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*Foo\) to type T: cannot convert \*Foo \(in X\) to type \*Far \(in T\) */)
8080
}
8181

8282
// Verify that the defined types in constraints are considered for the rule above.
@@ -109,14 +109,14 @@ func _[X Float, T Float](x X) T { return T(x) }
109109

110110
func _[X, T Integer | Unsigned | Float](x X) T { return T(x) }
111111
func _[X, T Integer | ~string](x X) T {
112-
return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~string\) to type T:\n\tcannot convert string \(in X\) to type int \(in T\) */)
112+
return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~string\) to type T: cannot convert string \(in X\) to type int \(in T\) */)
113113
}
114114

115115
// "x's type and T are both complex types"
116116

117117
func _[X, T Complex](x X) T { return T(x) }
118118
func _[X, T Float | Complex](x X) T {
119-
return T(x /* ERROR cannot convert x \(variable of type X constrained by Float \| Complex\) to type T:\n\tcannot convert float32 \(in X\) to type complex64 \(in T\) */)
119+
return T(x /* ERROR cannot convert x \(variable of type X constrained by Float \| Complex\) to type T: cannot convert float32 \(in X\) to type complex64 \(in T\) */)
120120
}
121121

122122
// "x is an integer or a slice of bytes or runes and T is a string type"
@@ -129,7 +129,7 @@ func _[T ~string](x myInt) T { return T(x) }
129129
func _[X Integer](x X) string { return string(x) }
130130
func _[X Integer](x X) myString { return myString(x) }
131131
func _[X Integer](x X) *string {
132-
return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to type \*string:\n\tcannot convert int \(in X\) to type \*string */)
132+
return (*string)(x /* ERROR cannot convert x \(variable of type X constrained by Integer\) to type \*string: cannot convert int \(in X\) to type \*string */)
133133
}
134134

135135
func _[T ~string](x []byte) T { return T(x) }
@@ -138,22 +138,22 @@ func _[X ~[]byte, T ~string](x X) T { return T(x) }
138138
func _[X ~[]rune, T ~string](x X) T { return T(x) }
139139
func _[X Integer | ~[]byte | ~[]rune, T ~string](x X) T { return T(x) }
140140
func _[X Integer | ~[]byte | ~[]rune, T ~*string](x X) T {
141-
return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~\[\]byte \| ~\[\]rune\) to type T:\n\tcannot convert int \(in X\) to type \*string \(in T\) */)
141+
return T(x /* ERROR cannot convert x \(variable of type X constrained by Integer \| ~\[\]byte \| ~\[\]rune\) to type T: cannot convert int \(in X\) to type \*string \(in T\) */)
142142
}
143143

144144
// "x is a string and T is a slice of bytes or runes"
145145

146146
func _[T ~[]byte](x string) T { return T(x) }
147147
func _[T ~[]rune](x string) T { return T(x) }
148148
func _[T ~[]rune](x *string) T {
149-
return T(x /* ERROR cannot convert x \(variable of type \*string\) to type T:\n\tcannot convert \*string to type \[\]rune \(in T\) */)
149+
return T(x /* ERROR cannot convert x \(variable of type \*string\) to type T: cannot convert \*string to type \[\]rune \(in T\) */)
150150
}
151151

152152
func _[X ~string, T ~[]byte](x X) T { return T(x) }
153153
func _[X ~string, T ~[]rune](x X) T { return T(x) }
154154
func _[X ~string, T ~[]byte | ~[]rune](x X) T { return T(x) }
155155
func _[X ~*string, T ~[]byte | ~[]rune](x X) T {
156-
return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to type T:\n\tcannot convert \*string \(in X\) to type \[\]byte \(in T\) */)
156+
return T(x /* ERROR cannot convert x \(variable of type X constrained by ~\*string\) to type T: cannot convert \*string \(in X\) to type \[\]byte \(in T\) */)
157157
}
158158

159159
// package unsafe:
@@ -164,7 +164,7 @@ type myUintptr uintptr
164164
func _[X ~uintptr](x X) unsafe.Pointer { return unsafe.Pointer(x) }
165165
func _[T unsafe.Pointer](x myUintptr) T { return T(x) }
166166
func _[T unsafe.Pointer](x int64) T {
167-
return T(x /* ERROR cannot convert x \(variable of type int64\) to type T:\n\tcannot convert int64 to type unsafe\.Pointer \(in T\) */)
167+
return T(x /* ERROR cannot convert x \(variable of type int64\) to type T: cannot convert int64 to type unsafe\.Pointer \(in T\) */)
168168
}
169169

170170
// "and vice versa"
@@ -173,7 +173,7 @@ func _[T ~uintptr](x unsafe.Pointer) T { return T(x) }
173173
func _[X unsafe.Pointer](x X) uintptr { return uintptr(x) }
174174
func _[X unsafe.Pointer](x X) myUintptr { return myUintptr(x) }
175175
func _[X unsafe.Pointer](x X) int64 {
176-
return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to type int64:\n\tcannot convert unsafe\.Pointer \(in X\) to type int64 */)
176+
return int64(x /* ERROR cannot convert x \(variable of type X constrained by unsafe\.Pointer\) to type int64: cannot convert unsafe\.Pointer \(in X\) to type int64 */)
177177
}
178178

179179
// "x is a slice, T is an array or pointer-to-array type,

test/alias2.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ var _ A0 = T0{}
4646
var _ T0 = A0{}
4747

4848
// But aliases and original types cannot be used with new types based on them.
49-
var _ N0 = T0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|cannot use T0{} \(value of type T0\) as type N0 in variable declaration"
50-
var _ N0 = A0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|cannot use A0{} \(value of type T0\) as type N0 in variable declaration"
49+
var _ N0 = T0{} // ERROR "cannot use T0{} \(value of type T0\) as N0 value in variable declaration"
50+
var _ N0 = A0{} // ERROR "cannot use A0{} \(value of type T0\) as N0 value in variable declaration"
5151

5252
var _ A5 = Value{}
5353

@@ -82,10 +82,10 @@ func _() {
8282
var _ A0 = T0{}
8383
var _ T0 = A0{}
8484

85-
var _ N0 = T0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|cannot use T0{} \(value of type T0\) as type N0 in variable declaration"
86-
var _ N0 = A0{} // ERROR "cannot use T0{} \(type T0\) as type N0 in assignment|cannot use A0{} \(value of type T0\) as type N0 in variable declaration"
85+
var _ N0 = T0{} // ERROR "cannot use T0{} \(value of type T0\) as N0 value in variable declaration"
86+
var _ N0 = A0{} // ERROR "cannot use A0{} \(value of type T0\) as N0 value in variable declaration"
8787

88-
var _ A5 = Value{} // ERROR "cannot use reflect\.Value{} \(type reflect.Value\) as type A5 in assignment|cannot use Value{} \(value of type reflect.Value\) as type A5 in variable declaration"
88+
var _ A5 = Value{} // ERROR "cannot use Value{} \(value of type reflect\.Value\) as A5 value in variable declaration"
8989
}
9090

9191
// Invalid type alias declarations.

test/append1.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ func main() {
1717
_ = append(s...) // ERROR "cannot use ... on first argument|not enough arguments in call to append"
1818
_ = append(s, 2, s...) // ERROR "too many arguments to append|too many arguments in call to append"
1919

20-
_ = append(s, make([]int, 0)) // ERROR "cannot use make.* as type int in append|cannot use make.* \(value of type \[\]int\) as type int in argument to append"
20+
_ = append(s, make([]int, 0)) // ERROR "cannot use make\(\[\]int, 0\) \(value of type \[\]int\) as int value in argument to append"
2121
_ = append(s, make([]int, -1)...) // ERROR "negative len argument in make|index -1.* must not be negative"
2222
}

test/ddd1.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var (
1919
_ = sum(1.0, 2.0)
2020
_ = sum(1.5) // ERROR "1\.5 .untyped float constant. as int|integer"
2121
_ = sum("hello") // ERROR ".hello. (.untyped string constant. as int|.type untyped string. as type int)|incompatible"
22-
_ = sum([]int{1}) // ERROR "\[\]int{.*}.*as type int"
22+
_ = sum([]int{1}) // ERROR "\[\]int{.*}.*as int value"
2323
)
2424

2525
func sum3(int, int, int) int { return 0 }

test/fixedbugs/bug389.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@ package foo
99

1010
func fn(a float32) {}
1111

12-
var f func(arg int) = fn // ERROR "cannot use fn .type func.float32.. as type func.int. in assignment|different parameter types|cannot use fn .*type func.*float32.. as type func.*int. in variable declaration"
12+
var f func(arg int) = fn // ERROR "different parameter types|cannot use fn .*type func.*float32.. as func.*int. value in variable declaration"

test/fixedbugs/issue17645.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ type Foo struct {
1212

1313
func main() {
1414
var s []int
15-
var _ string = append(s, Foo{""}) // ERROR "cannot use .. \(.*untyped string.*\) as .*int.*|incompatible type" "cannot use Foo{.*} \(.*type Foo\) as type int in .*append" "cannot use append\(s\, Foo{.*}\) \(.*type \[\]int\) as type string in (assignment|variable declaration)"
15+
var _ string = append(s, Foo{""}) // ERROR "cannot use append\(s, Foo{…}\) .* as string value in variable declaration" "cannot use Foo{…} .* as int value in argument to append" "cannot use .* as int value in struct literal"
1616
}

test/fixedbugs/issue48471.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,24 @@ func (T6) m(int) string { return "" }
3333
func f(I)
3434

3535
func g() {
36-
f(new(T)) // ERROR "cannot use new\(T\) \(.*type \*T\) as type I in argument to f:\n\t\*T does not implement I \(missing method M\)"
36+
f(new(T)) // ERROR "cannot use new\(T\) \(.*type \*T\) as I value in argument to f: \*T does not implement I \(missing method M\)"
3737

3838
var i I
39-
i = new(T) // ERROR "cannot use new\(T\) \(.*type \*T\) as type I in assignment:\n\t\*T does not implement I \(missing method M\)"
40-
i = I(new(T)) // ERROR "cannot convert new\(T\) \(.*type \*T\) to type I:\n\t\*T does not implement I \(missing method M\)"
41-
i = new(T2) // ERROR "cannot use new\(T2\) \(.*type \*T2\) as type I in assignment:\n\t\*T2 does not implement I \(missing method M\)\n\t\thave m\(int\)\n\t\twant M\(int\)"
39+
i = new(T) // ERROR "cannot use new\(T\) \(.*type \*T\) as I value in assignment: \*T does not implement I \(missing method M\)"
40+
i = I(new(T)) // ERROR "cannot convert new\(T\) \(.*type \*T\) to type I: \*T does not implement I \(missing method M\)"
41+
i = new(T2) // ERROR "cannot use new\(T2\) \(.*type \*T2\) as I value in assignment: \*T2 does not implement I \(missing method M\)\n\t\thave m\(int\)\n\t\twant M\(int\)"
4242

43-
i = new(T3) // ERROR "cannot use new\(T3\) \(.*type \*T3\) as type I in assignment:\n\t\*T3 does not implement I \(wrong type for method M\)\n\t\thave M\(string\)\n\t\twant M\(int\)"
43+
i = new(T3) // ERROR "cannot use new\(T3\) \(.*type \*T3\) as I value in assignment: \*T3 does not implement I \(wrong type for method M\)\n\t\thave M\(string\)\n\t\twant M\(int\)"
4444

45-
i = T4{} // ERROR "cannot use T4\{\} \(.*type T4\) as type I in assignment:\n\tT4 does not implement I \(method M has pointer receiver\)"
46-
i = new(I) // ERROR "cannot use new\(I\) \(.*type \*I\) as type I in assignment:\n\t\*I does not implement I \(type \*I is pointer to interface, not interface\)"
45+
i = T4{} // ERROR "cannot use T4\{\} \(.*type T4\) as I value in assignment: T4 does not implement I \(method M has pointer receiver\)"
46+
i = new(I) // ERROR "cannot use new\(I\) \(.*type \*I\) as I value in assignment: \*I does not implement I \(type \*I is pointer to interface, not interface\)"
4747

4848
_ = i.(*T2) // ERROR "impossible type assertion: i.\(\*T2\)\n\t\*T2 does not implement I \(missing method M\)\n\t\thave m\(int\)\n\t\twant M\(int\)"
4949
_ = i.(*T3) // ERROR "impossible type assertion: i.\(\*T3\)\n\t\*T3 does not implement I \(wrong type for method M\)\n\t\thave M\(string\)\n\t\twant M\(int\)"
5050
_ = i.(T5) // ERROR ""impossible type assertion: i.\(T5\)\n\tT5 does not implement I \(missing method M\)\n\t\thave m\(int\)\n\t\twant M\(int\)"
5151
_ = i.(T6) // ERROR "impossible type assertion: i.\(T6\)\n\tT6 does not implement I \(missing method M\)\n\t\thave m\(int\) string\n\t\twant M\(int\)"
5252

5353
var t *T4
54-
t = i // ERROR "cannot use i \(variable of type I\) as type \*T4 in assignment:\n\tneed type assertion"
54+
t = i // ERROR "cannot use i \(variable of type I\) as \*T4 value in assignment: need type assertion"
5555
_ = i
5656
}

test/fixedbugs/issue5358.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ func f(x int, y ...int) {}
1313
func g() (int, []int)
1414

1515
func main() {
16-
f(g()) // ERROR "as type int in|incompatible type"
16+
f(g()) // ERROR "as int value in|incompatible type"
1717
}

0 commit comments

Comments
 (0)