aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck
diff options
context:
space:
mode:
authorMichael Matloob <matloob@golang.org>2021-08-26 15:04:40 -0400
committerMichael Matloob <matloob@golang.org>2021-08-26 15:04:42 -0400
commitde83ef67acaaf5c2ce12dd831e8d3d04f02a6fc9 (patch)
treede1e9db916cb810d3360137a7b5ead7c00f7bce5 /src/cmd/compile/internal/typecheck
parentde23549a3967ade982d848a5b6ae3cb3fa0dba45 (diff)
parent5e6a7e9b860d7c8f589eec3c123469ea8071689f (diff)
downloadgo-de83ef67acaaf5c2ce12dd831e8d3d04f02a6fc9.tar.gz
go-de83ef67acaaf5c2ce12dd831e8d3d04f02a6fc9.zip
[dev.cmdgo] all: merge master (5e6a7e9) into dev.cmdgo
Merge List: + 2021-08-26 5e6a7e9b86 embed: remove reference to global variables in docs + 2021-08-26 166b691b65 cmd/compile/internal/types2: remove need for instance (struct) + 2021-08-26 d6bdae33e9 cmd/compile/internal/types2: address some TODOs (cleanup) + 2021-08-26 770df2e18d crypto/tls: fix typo in PreferServerCipherSuites comment + 2021-08-26 a6ff433d6a cmd/go: pass -gcflags after other flags generated by the go command + 2021-08-25 4f2620285d cmd/compile/internal/types2: fix type set printing and add test + 2021-08-25 0ac64f6d70 cmd/compile/internal/types2: rename IsMethodSet to IsConstraint (cleanup) + 2021-08-25 4068fb6c21 cmd/compile: always accept 1.18 syntax but complain if not 1.18 + 2021-08-25 bf0bc4122f go/types, types2: don't re-evaluate context string for each function argument (optimization) + 2021-08-25 4158e88f64 cmd/compile/internal/syntax: fix position of type parameter field + 2021-08-25 647bef6c59 go/types: implement NewTypeList and use it instead of composite literals + 2021-08-25 6cf1d5d0fa cmd/compile: generic SSA rules for simplifying 2 and 3 operand integer arithmetic expressions + 2021-08-25 5baf60d472 bytes, strings: optimize Trim for single byte cutsets + 2021-08-25 3d667671ad cmd/compile: fix function contains no TParam in generic function + 2021-08-25 4f2ebfe34b cmd/compile: allow embed into any byte slice type + 2021-08-25 d2f002cb39 time/format: avoid growslice in time.String()/time.GoString() + 2021-08-25 08d4cc20ca cmd/compile: fix stencil call expression. + 2021-08-25 099b819085 cmd/compile: fix CheckSize() calculation for -G=3 and stencils + 2021-08-25 e1fcf8857e test: add test that caused gofrontend compiler crash + 2021-08-25 d37b8dedf7 test: add test case that gofrontend miscompiled + 2021-08-25 41b99dab0f os/user: don't skip TestLookupGroup if supported + 2021-08-25 de1c934b97 cmd/compile: fix checkptr false positive for (*[Big]T)(ptr)[:n:n] pattern + 2021-08-24 54cdef1f10 reflect: add MapIter.SetKey and MapIter.SetValue + 2021-08-24 5d863f89fe cmd/compile: simplify bad conversion check Change-Id: I29ab927f0e47f44d82f9307c642900f75f4f678f
Diffstat (limited to 'src/cmd/compile/internal/typecheck')
-rw-r--r--src/cmd/compile/internal/typecheck/subr.go55
1 files changed, 30 insertions, 25 deletions
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
index 7ae10ef406..8d05356543 100644
--- a/src/cmd/compile/internal/typecheck/subr.go
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -1003,6 +1003,15 @@ type Tsubster struct {
// result is t; otherwise the result is a new type. It deals with recursive types
// by using TFORW types and finding partially or fully created types via sym.Def.
func (ts *Tsubster) Typ(t *types.Type) *types.Type {
+ // Defer the CheckSize calls until we have fully-defined
+ // (possibly-recursive) top-level type.
+ types.DeferCheckSize()
+ r := ts.typ1(t)
+ types.ResumeCheckSize()
+ return r
+}
+
+func (ts *Tsubster) typ1(t *types.Type) *types.Type {
if !t.HasTParam() && t.Kind() != types.TFUNC {
// Note: function types need to be copied regardless, as the
// types of closures may contain declarations that need
@@ -1042,12 +1051,13 @@ func (ts *Tsubster) Typ(t *types.Type) *types.Type {
var targsChanged bool
var forw *types.Type
- if t.Sym() != nil {
+ if t.Sym() != nil && t.HasTParam() {
+ // Need to test for t.HasTParam() again because of special TFUNC case above.
// Translate the type params for this type according to
// the tparam/targs mapping from subst.
neededTargs = make([]*types.Type, len(t.RParams()))
for i, rparam := range t.RParams() {
- neededTargs[i] = ts.Typ(rparam)
+ neededTargs[i] = ts.typ1(rparam)
if !types.Identical(neededTargs[i], rparam) {
targsChanged = true
}
@@ -1085,26 +1095,26 @@ func (ts *Tsubster) Typ(t *types.Type) *types.Type {
}
// Substitute the underlying typeparam (e.g. T in P[T], see
// the example describing type P[T] above).
- newt = ts.Typ(t.Underlying())
+ newt = ts.typ1(t.Underlying())
assert(newt != t)
case types.TARRAY:
elem := t.Elem()
- newelem := ts.Typ(elem)
+ newelem := ts.typ1(elem)
if newelem != elem || targsChanged {
newt = types.NewArray(newelem, t.NumElem())
}
case types.TPTR:
elem := t.Elem()
- newelem := ts.Typ(elem)
+ newelem := ts.typ1(elem)
if newelem != elem || targsChanged {
newt = types.NewPtr(newelem)
}
case types.TSLICE:
elem := t.Elem()
- newelem := ts.Typ(elem)
+ newelem := ts.typ1(elem)
if newelem != elem || targsChanged {
newt = types.NewSlice(newelem)
}
@@ -1159,22 +1169,17 @@ func (ts *Tsubster) Typ(t *types.Type) *types.Type {
}
case types.TMAP:
- newkey := ts.Typ(t.Key())
- newval := ts.Typ(t.Elem())
+ newkey := ts.typ1(t.Key())
+ newval := ts.typ1(t.Elem())
if newkey != t.Key() || newval != t.Elem() || targsChanged {
newt = types.NewMap(newkey, newval)
}
case types.TCHAN:
elem := t.Elem()
- newelem := ts.Typ(elem)
+ newelem := ts.typ1(elem)
if newelem != elem || targsChanged {
newt = types.NewChan(newelem, t.ChanDir())
- if !newt.HasTParam() {
- // TODO(danscales): not sure why I have to do this
- // only for channels.....
- types.CheckSize(newt)
- }
}
case types.TFORW:
if ts.SubstForwFunc != nil {
@@ -1194,7 +1199,7 @@ func (ts *Tsubster) Typ(t *types.Type) *types.Type {
for i := 0; i < nt; i++ {
term, tilde := t.Term(i)
tildes[i] = tilde
- newterms[i] = ts.Typ(term)
+ newterms[i] = ts.typ1(term)
if newterms[i] != term {
changed = true
}
@@ -1212,24 +1217,24 @@ func (ts *Tsubster) Typ(t *types.Type) *types.Type {
return t
}
- if t.Sym() == nil && t.Kind() != types.TINTER {
- // Not a named type or interface type, so there was no forwarding type
- // and there are no methods to substitute.
- assert(t.Methods().Len() == 0)
- return newt
- }
-
if forw != nil {
forw.SetUnderlying(newt)
newt = forw
}
+ if !newt.HasTParam() {
+ // Calculate the size of any new types created. These will be
+ // deferred until the top-level ts.Typ() or g.typ() (if this is
+ // called from g.fillinMethods()).
+ types.CheckSize(newt)
+ }
+
if t.Kind() != types.TINTER && t.Methods().Len() > 0 {
// Fill in the method info for the new type.
var newfields []*types.Field
newfields = make([]*types.Field, t.Methods().Len())
for i, f := range t.Methods().Slice() {
- t2 := ts.Typ(f.Type)
+ t2 := ts.typ1(f.Type)
oldsym := f.Nname.Sym()
newsym := MakeFuncInstSym(oldsym, ts.Targs, true)
var nname *ir.Name
@@ -1272,7 +1277,7 @@ func (ts *Tsubster) tstruct(t *types.Type, force bool) *types.Type {
newfields = make([]*types.Field, t.NumFields())
}
for i, f := range t.Fields().Slice() {
- t2 := ts.Typ(f.Type)
+ t2 := ts.typ1(f.Type)
if (t2 != f.Type || f.Nname != nil) && newfields == nil {
newfields = make([]*types.Field, t.NumFields())
for j := 0; j < i; j++ {
@@ -1325,7 +1330,7 @@ func (ts *Tsubster) tinter(t *types.Type) *types.Type {
}
var newfields []*types.Field
for i, f := range t.Methods().Slice() {
- t2 := ts.Typ(f.Type)
+ t2 := ts.typ1(f.Type)
if (t2 != f.Type || f.Nname != nil) && newfields == nil {
newfields = make([]*types.Field, t.Methods().Len())
for j := 0; j < i; j++ {