In Checker.typInternal, the SelectorExpr case was the only case that
didn't either set or pass along the incoming def *Named type.
Handle this by passing it along to Checker.selector and report a
cycle if one is detected.
Fixes #51509.
Change-Id: I6c2d46835f225aeb4cb25fe0ae55f6180cef038b
Reviewed-on: https://go-review.googlesource.com/c/go/+/390314
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
(cherry picked from commit
114d5deac2f513a7397ab4c2ee8d2d567a901266)
Reviewed-on: https://go-review.googlesource.com/c/go/+/390423
Trust: Dmitri Shuralyov <dmitshur@golang.org>
Run-TryBot: Dmitri Shuralyov <dmitshur@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
"_Cmacro_", // function to evaluate the expanded expression
}
-func (check *Checker) selector(x *operand, e *syntax.SelectorExpr) {
+func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
// these must be declared before the "goto Error" statements
var (
obj Object
check.exprOrType(x, e.X, false)
switch x.mode {
+ case typexpr:
+ // don't crash for "type T T.x" (was issue #51509)
+ if def != nil && x.typ == def {
+ check.cycleError([]Object{def.obj})
+ goto Error
+ }
case builtin:
check.errorf(e.Pos(), "cannot select on %s", x)
goto Error
return kind
case *syntax.SelectorExpr:
- check.selector(x, e)
+ check.selector(x, e, nil)
case *syntax.IndexExpr:
if check.indexExpr(x, e) {
--- /dev/null
+// Copyright 2022 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 T /* ERROR illegal cycle */ T.x
case *syntax.SelectorExpr:
var x operand
- check.selector(&x, e)
+ check.selector(&x, e, def)
switch x.mode {
case typexpr:
"_Cmacro_", // function to evaluate the expanded expression
}
-func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
+func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named) {
// these must be declared before the "goto Error" statements
var (
obj Object
check.exprOrType(x, e.X, false)
switch x.mode {
+ case typexpr:
+ // don't crash for "type T T.x" (was issue #51509)
+ if def != nil && x.typ == def {
+ check.cycleError([]Object{def.obj})
+ goto Error
+ }
case builtin:
// types2 uses the position of '.' for the error
check.errorf(e.Sel, _UncalledBuiltin, "cannot select on %s", x)
return kind
case *ast.SelectorExpr:
- check.selector(x, e)
+ check.selector(x, e, nil)
case *ast.IndexExpr, *ast.IndexListExpr:
ix := typeparams.UnpackIndexExpr(e)
--- /dev/null
+// Copyright 2022 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 T /* ERROR illegal cycle */ T.x
case *ast.SelectorExpr:
var x operand
- check.selector(&x, e)
+ check.selector(&x, e, def)
switch x.mode {
case typexpr: