]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/go/types/mono.go
go/types, types2: implement Alias proposal (export API)
[gostls13.git] / src / go / types / mono.go
index fb1127e959fa89598747202df3c4db2a482811d7..74113392149fbdc1362af3d085496b8daf907b12 100644 (file)
@@ -5,7 +5,9 @@
 package types
 
 import (
+       "go/ast"
        "go/token"
+       . "internal/types/errors"
 )
 
 // This file implements a check to validate that a Go package doesn't
@@ -71,14 +73,11 @@ type monoVertex struct {
 }
 
 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() {
@@ -139,12 +138,22 @@ func (check *Checker) reportInstanceLoop(v int) {
 
        // 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
+               }
        }
 }
 
@@ -159,11 +168,11 @@ func (w *monoGraph) recordCanon(mpar, tpar *TypeParam) {
 
 // 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])
        }
@@ -190,17 +199,14 @@ func (w *monoGraph) assign(pkg *Package, pos token.Pos, tpar *TypeParam, targ Ty
                        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")
 
@@ -276,16 +282,14 @@ func (w *monoGraph) localNamedVertex(pkg *Package, named *Named) int {
        // 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)
                                }
                        }
                }
@@ -320,12 +324,14 @@ func (w *monoGraph) typeParamVertex(tpar *TypeParam) int {
        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,
        })
 }