}
check.recordUse(e, obj)
+ // If we want a type but don't have one, stop right here and avoid potential problems
+ // with missing underlying types. This also gives better error messages in some cases
+ // (see go.dev/issue/65344).
+ _, gotType := obj.(*TypeName)
+ if !gotType && wantType {
+ check.errorf(e, NotAType, "%s is not a type", obj.Name())
+ // avoid "declared but not used" errors
+ // (don't use Checker.use - we don't want to evaluate too much)
+ if v, _ := obj.(*Var); v != nil && v.pkg == check.pkg /* see Checker.use1 */ {
+ v.used = true
+ }
+ return
+ }
+
// Type-check the object.
// Only call Checker.objDecl if the object doesn't have a type yet
// (in which case we must actually determine it) or the object is a
// informative "not a type/value" error that this function's caller
// will issue (see go.dev/issue/25790).
typ := obj.Type()
- if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
+ if typ == nil || gotType && wantType {
check.objDecl(obj, def)
typ = obj.Type() // type must have been assigned by Checker.objDecl
}
}
check.recordUse(e, obj)
+ // If we want a type but don't have one, stop right here and avoid potential problems
+ // with missing underlying types. This also gives better error messages in some cases
+ // (see go.dev/issue/65344).
+ _, gotType := obj.(*TypeName)
+ if !gotType && wantType {
+ check.errorf(e, NotAType, "%s is not a type", obj.Name())
+ // avoid "declared but not used" errors
+ // (don't use Checker.use - we don't want to evaluate too much)
+ if v, _ := obj.(*Var); v != nil && v.pkg == check.pkg /* see Checker.use1 */ {
+ v.used = true
+ }
+ return
+ }
+
// Type-check the object.
// Only call Checker.objDecl if the object doesn't have a type yet
// (in which case we must actually determine it) or the object is a
// informative "not a type/value" error that this function's caller
// will issue (see go.dev/issue/25790).
typ := obj.Type()
- if _, gotType := obj.(*TypeName); typ == nil || gotType && wantType {
+ if typ == nil || gotType && wantType {
check.objDecl(obj, def)
typ = obj.Type() // type must have been assigned by Checker.objDecl
}
func makeArray() (res T12) { return }
// issue #20770
-var r /* ERROR "invalid cycle in declaration of r" */ = newReader()
-func newReader() r
+var r = newReader()
+func newReader() r // ERROR "r is not a type"
// variations of the theme of #8699 and #20770
var arr /* ERROR "cycle" */ = f()
func makeArray() (res T12) { return }
// issue #20770
-var r /* ERROR "invalid cycle in declaration of r" */ = newReader()
-func newReader() r
+var r = newReader()
+func newReader() r // ERROR "r is not a type"
// variations of the theme of #8699 and #20770
var arr /* ERROR "cycle" */ = f()
t12 complex64 = -(u + *t11) / *&v
t13 int = a /* ERROR "shifted operand" */ << d
t14 int = i << j
- t15 math /* ERROR "not in selector" */
+ t15 math /* ERROR "math is not a type" */
t16 math.xxx /* ERROR "undefined" */
t17 math /* ERROR "not a type" */ .Pi
t18 float64 = math.Pi * 10.0
// issue11347
// These should not crash.
-var a1, b1 /* ERROR "cycle" */ , c1 /* ERROR "cycle" */ b1 = 0 > 0<<""[""[c1]]>c1
+var a1, b1, c1 /* ERROR "cycle" */ b1 /* ERROR "b1 is not a type" */ = 0 > 0<<""[""[c1]]>c1
var a2, b2 /* ERROR "cycle" */ = 0 /* ERROR "assignment mismatch" */ /* ERROR "assignment mismatch" */ > 0<<""[b2]
var a3, b3 /* ERROR "cycle" */ = int /* ERROR "assignment mismatch" */ /* ERROR "assignment mismatch" */ (1<<""[b3])
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Examples adjusted to match new [T any] syntax for type parameters.
+// Examples from the issue adjusted to match new [T any] syntax for type parameters.
// Also, previously permitted empty type parameter lists and instantiations
// are now syntax errors.
+//
+// The primary concern here is that these tests shouldn't crash the type checker.
+// The quality of the error messages is secondary as these are all pretty esoteric
+// or artificial test cases.
package p
func _() { var _ = new(foo9[int]) }
// crash 12
-var u /* ERROR "cycle" */ , i [func /* ERROR "used as value" */ /* ERROR "used as value" */ (u, c /* ERROR "undefined" */ /* ERROR "undefined" */ ) {}(0, len /* ERROR "must be called" */ /* ERROR "must be called" */ )]c /* ERROR "undefined" */ /* ERROR "undefined" */
+var u, i [func /* ERROR "used as value" */ /* ERROR "used as value" */ (u /* ERROR "u is not a type" */ /* ERROR "u is not a type" */ , c /* ERROR "undefined" */ /* ERROR "undefined" */ ) {}(0, len /* ERROR "must be called" */ /* ERROR "must be called" */ )]c /* ERROR "undefined" */ /* ERROR "undefined" */
// crash 15
func y15() { var a /* ERROR "declared and not used" */ interface{ p() } = G15[string]{} }
--- /dev/null
+// Copyright 2024 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 T1 C /* ERROR "C is not a type" */
+
+// TODO(gri) try to avoid this follow-on error
+const C = T1(0 /* ERROR "cannot convert 0 (untyped int constant) to type T1" */)
+
+type T2 V /* ERROR "V is not a type" */
+
+var V T2
+
+func _() {
+ // don't produce errors here
+ _ = C + V
+}