From a76283d6e45673fa43ba2144aca2d07864b1ed72 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 8 Jul 2019 16:58:05 -0700 Subject: [PATCH] go/types: add primitive instantiated type map for canonicalization Change-Id: I265105d483b6fdcee95f3770b9d6d774c1633638 --- src/go/types/check.go | 5 ++++- src/go/types/errors.go | 4 ++++ src/go/types/subst.go | 13 ++++++++++--- src/go/types/testdata/typeinst.go2 | 15 +++++++++++---- 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/src/go/types/check.go b/src/go/types/check.go index e15acbefcd..62d2ade1a7 100644 --- a/src/go/types/check.go +++ b/src/go/types/check.go @@ -16,8 +16,9 @@ import ( // debugging/development support const ( - debug = true // leave on during development + debug = false // leave on during development trace = false // turn on for detailed type resolution traces + halt = false // panic on error ) // If Strict is set, the type-checker enforces additional @@ -81,6 +82,7 @@ type Checker struct { objMap map[Object]*declInfo // maps package-level objects and (non-interface) methods to declaration info impMap map[importKey]*Package // maps (import path, source directory) to (complete or fake) package posMap map[*Interface][]token.Pos // maps interface types to lists of embedded interface positions + typMap map[string]*TypeName // maps an instantiated type to a *Named type -- TODO(gri) this is a quick hack; fix this pkgCnt map[string]int // counts number of imported packages with a given name (for better error messages) // information collected during type-checking of a set of package files @@ -193,6 +195,7 @@ func NewChecker(conf *Config, fset *token.FileSet, pkg *Package, info *Info) *Ch objMap: make(map[Object]*declInfo), impMap: make(map[importKey]*Package), posMap: make(map[*Interface][]token.Pos), + typMap: make(map[string]*TypeName), pkgCnt: make(map[string]int), } } diff --git a/src/go/types/errors.go b/src/go/types/errors.go index 91b077163c..9efd701fb6 100644 --- a/src/go/types/errors.go +++ b/src/go/types/errors.go @@ -90,6 +90,10 @@ func (check *Checker) err(pos token.Pos, msg string, soft bool) { if trace { check.trace(pos, "ERROR: %s", msg) } + + if halt { + panic(err) + } f := check.conf.Error if f == nil { diff --git a/src/go/types/subst.go b/src/go/types/subst.go index 76ef5f3828..955585c713 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -102,12 +102,19 @@ func (s *subster) typ(typ Type) (res Type) { if len(t.methods) > 0 { panic("cannot handle instantiation of types with methods yet") } - // TODO(gri) what is the correct position to use here? - obj := NewTypeName(t.obj.pos, s.check.pkg, t.obj.name+typesString(s.targs), nil) - return NewNamed(obj, underlying, nil) // TODO(gri) provide correct method list + name := t.obj.name + typesString(s.targs) + tname, found := s.check.typMap[name] + if !found { + // TODO(gri) what is the correct position to use here? + tname = NewTypeName(t.obj.pos, s.check.pkg, name, nil) + NewNamed(tname, underlying, nil) // TODO(gri) provide correct method list + s.check.typMap[name] = tname + } + return tname.typ } case *TypeParam: + // TODO(gri) do we need to check that we're using the correct targs list/index? if targ := s.targs[t.index]; targ != nil { return targ } diff --git a/src/go/types/testdata/typeinst.go2 b/src/go/types/testdata/typeinst.go2 index 6e1336d5e3..a5c90c3355 100644 --- a/src/go/types/testdata/typeinst.go2 +++ b/src/go/types/testdata/typeinst.go2 @@ -47,11 +47,18 @@ var _ A1(float32) = x // ERROR cannot use x .* as float32 var _ T2(*int) = A2(*int){} var _ T2(*int) = A2 /* ERROR cannot use */ (int){} +var _ T2(int) = T2(int){} + +var _ List(int) = []int{1, 2, 3} +var _ List([]int) = [][]int{{1, 2, 3}} +// var _ List(List(int)) // TODO(gri) cannot not do this yet + +// Parametrized types containing parametrized types + +type T3(type P) = List(P) + +// var _ T3(int) = List(int){1, 2, 3} // TODO(gri) cannot do this yet -// TODO(gri) cannot handle this yet due because instantiated types are not yet canonicalized -//var _ T2(int) = T2(int){} // TODO -// think about instantiated types (they are defined types unless alias) -// need type map // type map maps to unique name found in scopes?