package types
import (
+ "go/ast"
"go/token"
+ . "internal/types/errors"
)
// This file implements a check to validate that a Go package doesn't
}
type monoEdge struct {
- dst int
- src int
- weight int
+ dst, src int
+ weight int
- // report emits an error describing why this edge exists.
- //
- // TODO(mdempsky): Avoid requiring a function closure for each edge.
- report func(check *Checker)
+ pos token.Pos
+ typ Type
}
func (check *Checker) monomorph() {
// TODO(mdempsky): Pivot stack so we report the cycle from the top?
- obj := check.mono.vertices[v].obj
- check.errorf(obj, _InvalidInstanceCycle, "instantiation cycle:")
+ obj0 := check.mono.vertices[v].obj
+ check.error(obj0, InvalidInstanceCycle, "instantiation cycle:")
+ qf := RelativeTo(check.pkg)
for _, v := range stack {
edge := check.mono.edges[check.mono.vertices[v].pre]
- edge.report(check)
+ obj := check.mono.vertices[edge.dst].obj
+
+ switch obj.Type().(type) {
+ default:
+ panic("unexpected type")
+ case *Named:
+ check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+ case *TypeParam:
+ check.errorf(atPos(edge.pos), InvalidInstanceCycle, "\t%s instantiated as %s", obj.Name(), TypeString(edge.typ, qf)) // secondary error, \t indented
+ }
}
}
// recordInstance records that the given type parameters were
// instantiated with the corresponding type arguments.
-func (w *monoGraph) recordInstance(pkg *Package, pos token.Pos, tparams []*TypeParam, targs []Type, posList []token.Pos) {
+func (w *monoGraph) recordInstance(pkg *Package, pos token.Pos, tparams []*TypeParam, targs []Type, xlist []ast.Expr) {
for i, tpar := range tparams {
pos := pos
- if i < len(posList) {
- pos = posList[i]
+ if i < len(xlist) {
+ pos = xlist[i].Pos()
}
w.assign(pkg, pos, tpar, targs[i])
}
weight = 0
}
- w.addEdge(w.typeParamVertex(tpar), src, weight, func(check *Checker) {
- qf := RelativeTo(check.pkg)
- check.errorf(atPos(pos), _InvalidInstanceCycle, "\t%s instantiated as %s", tpar.Obj().Name(), TypeString(targ, qf)) // secondary error, \t indented
- })
+ w.addEdge(w.typeParamVertex(tpar), src, weight, pos, targ)
}
// Recursively walk the type argument to find any defined types or
// type parameters.
var do func(typ Type)
do = func(typ Type) {
- switch typ := typ.(type) {
+ switch typ := Unalias(typ).(type) {
default:
panic("unexpected type")
// parameters that it's implicitly parameterized by.
for scope := obj.Parent(); scope != root; scope = scope.Parent() {
for _, elem := range scope.elems {
- if elem, ok := elem.(*TypeName); ok && !elem.IsAlias() && elem.Pos() < obj.Pos() {
+ if elem, ok := elem.(*TypeName); ok && !elem.IsAlias() && cmpPos(elem.Pos(), obj.Pos()) < 0 {
if tpar, ok := elem.Type().(*TypeParam); ok {
if idx < 0 {
idx = len(w.vertices)
w.vertices = append(w.vertices, monoVertex{obj: obj})
}
- w.addEdge(idx, w.typeParamVertex(tpar), 1, func(check *Checker) {
- check.errorf(obj, _InvalidInstanceCycle, "\t%s implicitly parameterized by %s", obj.Name(), elem.Name())
- })
+ w.addEdge(idx, w.typeParamVertex(tpar), 1, obj.Pos(), tpar)
}
}
}
return idx
}
-func (w *monoGraph) addEdge(dst, src, weight int, report func(check *Checker)) {
+func (w *monoGraph) addEdge(dst, src, weight int, pos token.Pos, typ Type) {
// TODO(mdempsky): Deduplicate redundant edges?
w.edges = append(w.edges, monoEdge{
dst: dst,
src: src,
weight: weight,
- report: report,
+
+ pos: pos,
+ typ: typ,
})
}