Skip to content

Commit

Permalink
go/types: better cycle reporting for some cyclic composite literals
Browse files Browse the repository at this point in the history
To evaluate the type of composite literals, the type checker called
Checker.typ which breaks cycles. As a result, certain cycles were
not reported with actual cycle reporting, but caught due to other
uninitialized fields (with less nice error message).

The change now calls Checker.typExpr at the relevant call site.

For #18643.

Change-Id: Iecb3f0e1afb4585b85553b6c581212f52ac3a1c4
Reviewed-on: https://go-review.googlesource.com/115456
Reviewed-by: Alan Donovan <adonovan@google.com>
  • Loading branch information
griesemer committed May 31, 2018
1 parent 462c182 commit 6dbaf03
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/go/types/builtins.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
}

if mode == invalid {
if mode == invalid && typ != Typ[Invalid] {
check.invalidArg(x.pos(), "%s for %s", x, bin.name)
return
}
Expand Down
2 changes: 1 addition & 1 deletion src/go/types/expr.go
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
break
}
}
typ = check.typ(e.Type)
typ = check.typExpr(e.Type, nil, nil)
base = typ

case hint != nil:
Expand Down
2 changes: 1 addition & 1 deletion src/go/types/testdata/cycles.src
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ type (
// test cases for issue 18643
// (type cycle detection when non-type expressions are involved)
type (
T14 [len(T14 /* ERROR cycle */ {})]int
T14 /* ERROR cycle */ [len(T14{})]int
T15 [][len(T15 /* ERROR cycle */ {})]int
T16 map[[len(T16 /* ERROR cycle */ {1:2})]int]int
T17 map[int][len(T17 /* ERROR cycle */ {1:2})]int
Expand Down
5 changes: 5 additions & 0 deletions src/go/types/typexpr.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type)
return
}

// typ is like typExpr (with a nil argument for the def parameter),
// but typ breaks type cycles. It should be called for components of
// types that break cycles, such as pointer base types, slice or map
// element types, etc. See the comment in typExpr for details.
//
func (check *Checker) typ(e ast.Expr) Type {
// typExpr is called with a nil path indicating an indirection:
// push indir sentinel on object path
Expand Down

0 comments on commit 6dbaf03

Please sign in to comment.