From 925182263164f44ec02bc90498da4b8dab4c9810 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Tue, 10 Jan 2023 14:18:06 -0800 Subject: [PATCH] go/types, types2: factor out under.go, generate it for go/types Change-Id: I581be544de313618ccd1e3ef4dc38f1ebf201b12 Reviewed-on: https://go-review.googlesource.com/c/go/+/461495 Reviewed-by: Robert Findley Run-TryBot: Robert Griesemer Auto-Submit: Robert Griesemer TryBot-Result: Gopher Robot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/types2/type.go | 109 --------------------- src/cmd/compile/internal/types2/under.go | 114 ++++++++++++++++++++++ src/go/types/generator.go | 1 + src/go/types/type.go | 109 --------------------- src/go/types/under.go | 116 +++++++++++++++++++++++ 5 files changed, 231 insertions(+), 218 deletions(-) create mode 100644 src/cmd/compile/internal/types2/under.go create mode 100644 src/go/types/under.go diff --git a/src/cmd/compile/internal/types2/type.go b/src/cmd/compile/internal/types2/type.go index 92ecf11559..bd194213b2 100644 --- a/src/cmd/compile/internal/types2/type.go +++ b/src/cmd/compile/internal/types2/type.go @@ -9,112 +9,3 @@ import "cmd/compile/internal/syntax" // A Type represents a type of Go. // All types implement the Type interface. type Type = syntax.Type - -// under returns the true expanded underlying type. -// If it doesn't exist, the result is Typ[Invalid]. -// under must only be called when a type is known -// to be fully set up. -func under(t Type) Type { - if t, _ := t.(*Named); t != nil { - return t.under() - } - return t.Underlying() -} - -// If t is not a type parameter, coreType returns the underlying type. -// If t is a type parameter, coreType returns the single underlying -// type of all types in its type set if it exists, or nil otherwise. If the -// type set contains only unrestricted and restricted channel types (with -// identical element types), the single underlying type is the restricted -// channel type if the restrictions are always the same, or nil otherwise. -func coreType(t Type) Type { - tpar, _ := t.(*TypeParam) - if tpar == nil { - return under(t) - } - - var su Type - if tpar.underIs(func(u Type) bool { - if u == nil { - return false - } - if su != nil { - u = match(su, u) - if u == nil { - return false - } - } - // su == nil || match(su, u) != nil - su = u - return true - }) { - return su - } - return nil -} - -// coreString is like coreType but also considers []byte -// and strings as identical. In this case, if successful and we saw -// a string, the result is of type (possibly untyped) string. -func coreString(t Type) Type { - tpar, _ := t.(*TypeParam) - if tpar == nil { - return under(t) // string or untyped string - } - - var su Type - hasString := false - if tpar.underIs(func(u Type) bool { - if u == nil { - return false - } - if isString(u) { - u = NewSlice(universeByte) - hasString = true - } - if su != nil { - u = match(su, u) - if u == nil { - return false - } - } - // su == nil || match(su, u) != nil - su = u - return true - }) { - if hasString { - return Typ[String] - } - return su - } - return nil -} - -// If x and y are identical, match returns x. -// If x and y are identical channels but for their direction -// and one of them is unrestricted, match returns the channel -// with the restricted direction. -// In all other cases, match returns nil. -func match(x, y Type) Type { - // Common case: we don't have channels. - if Identical(x, y) { - return x - } - - // We may have channels that differ in direction only. - if x, _ := x.(*Chan); x != nil { - if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) { - // We have channels that differ in direction only. - // If there's an unrestricted channel, select the restricted one. - switch { - case x.dir == SendRecv: - return y - case y.dir == SendRecv: - return x - } - } - } - - // types are different - return nil -} diff --git a/src/cmd/compile/internal/types2/under.go b/src/cmd/compile/internal/types2/under.go new file mode 100644 index 0000000000..887f7816ba --- /dev/null +++ b/src/cmd/compile/internal/types2/under.go @@ -0,0 +1,114 @@ +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types2 + +// under returns the true expanded underlying type. +// If it doesn't exist, the result is Typ[Invalid]. +// under must only be called when a type is known +// to be fully set up. +func under(t Type) Type { + if t, _ := t.(*Named); t != nil { + return t.under() + } + return t.Underlying() +} + +// If t is not a type parameter, coreType returns the underlying type. +// If t is a type parameter, coreType returns the single underlying +// type of all types in its type set if it exists, or nil otherwise. If the +// type set contains only unrestricted and restricted channel types (with +// identical element types), the single underlying type is the restricted +// channel type if the restrictions are always the same, or nil otherwise. +func coreType(t Type) Type { + tpar, _ := t.(*TypeParam) + if tpar == nil { + return under(t) + } + + var su Type + if tpar.underIs(func(u Type) bool { + if u == nil { + return false + } + if su != nil { + u = match(su, u) + if u == nil { + return false + } + } + // su == nil || match(su, u) != nil + su = u + return true + }) { + return su + } + return nil +} + +// coreString is like coreType but also considers []byte +// and strings as identical. In this case, if successful and we saw +// a string, the result is of type (possibly untyped) string. +func coreString(t Type) Type { + tpar, _ := t.(*TypeParam) + if tpar == nil { + return under(t) // string or untyped string + } + + var su Type + hasString := false + if tpar.underIs(func(u Type) bool { + if u == nil { + return false + } + if isString(u) { + u = NewSlice(universeByte) + hasString = true + } + if su != nil { + u = match(su, u) + if u == nil { + return false + } + } + // su == nil || match(su, u) != nil + su = u + return true + }) { + if hasString { + return Typ[String] + } + return su + } + return nil +} + +// If x and y are identical, match returns x. +// If x and y are identical channels but for their direction +// and one of them is unrestricted, match returns the channel +// with the restricted direction. +// In all other cases, match returns nil. +func match(x, y Type) Type { + // Common case: we don't have channels. + if Identical(x, y) { + return x + } + + // We may have channels that differ in direction only. + if x, _ := x.(*Chan); x != nil { + if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) { + // We have channels that differ in direction only. + // If there's an unrestricted channel, select the restricted one. + switch { + case x.dir == SendRecv: + return y + case y.dir == SendRecv: + return x + } + } + } + + // types are different + return nil +} diff --git a/src/go/types/generator.go b/src/go/types/generator.go index 2971b30511..eb9ee939f8 100644 --- a/src/go/types/generator.go +++ b/src/go/types/generator.go @@ -91,6 +91,7 @@ var filemap = map[string]action{ "typeparam.go": nil, "typeterm_test.go": nil, "typeterm.go": nil, + "under.go": nil, "universe.go": fixGlobalTypVarDecl, "validtype.go": nil, } diff --git a/src/go/types/type.go b/src/go/types/type.go index 130637530b..f6bd75908f 100644 --- a/src/go/types/type.go +++ b/src/go/types/type.go @@ -13,112 +13,3 @@ type Type interface { // String returns a string representation of a type. String() string } - -// under returns the true expanded underlying type. -// If it doesn't exist, the result is Typ[Invalid]. -// under must only be called when a type is known -// to be fully set up. -func under(t Type) Type { - if t, _ := t.(*Named); t != nil { - return t.under() - } - return t.Underlying() -} - -// If t is not a type parameter, coreType returns the underlying type. -// If t is a type parameter, coreType returns the single underlying -// type of all types in its type set if it exists, or nil otherwise. If the -// type set contains only unrestricted and restricted channel types (with -// identical element types), the single underlying type is the restricted -// channel type if the restrictions are always the same, or nil otherwise. -func coreType(t Type) Type { - tpar, _ := t.(*TypeParam) - if tpar == nil { - return under(t) - } - - var su Type - if tpar.underIs(func(u Type) bool { - if u == nil { - return false - } - if su != nil { - u = match(su, u) - if u == nil { - return false - } - } - // su == nil || match(su, u) != nil - su = u - return true - }) { - return su - } - return nil -} - -// coreString is like coreType but also considers []byte -// and strings as identical. In this case, if successful and we saw -// a string, the result is of type (possibly untyped) string. -func coreString(t Type) Type { - tpar, _ := t.(*TypeParam) - if tpar == nil { - return under(t) // string or untyped string - } - - var su Type - hasString := false - if tpar.underIs(func(u Type) bool { - if u == nil { - return false - } - if isString(u) { - u = NewSlice(universeByte) - hasString = true - } - if su != nil { - u = match(su, u) - if u == nil { - return false - } - } - // su == nil || match(su, u) != nil - su = u - return true - }) { - if hasString { - return Typ[String] - } - return su - } - return nil -} - -// If x and y are identical, match returns x. -// If x and y are identical channels but for their direction -// and one of them is unrestricted, match returns the channel -// with the restricted direction. -// In all other cases, match returns nil. -func match(x, y Type) Type { - // Common case: we don't have channels. - if Identical(x, y) { - return x - } - - // We may have channels that differ in direction only. - if x, _ := x.(*Chan); x != nil { - if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) { - // We have channels that differ in direction only. - // If there's an unrestricted channel, select the restricted one. - switch { - case x.dir == SendRecv: - return y - case y.dir == SendRecv: - return x - } - } - } - - // types are different - return nil -} diff --git a/src/go/types/under.go b/src/go/types/under.go new file mode 100644 index 0000000000..0c2410e74e --- /dev/null +++ b/src/go/types/under.go @@ -0,0 +1,116 @@ +// Code generated by "go run generator.go"; DO NOT EDIT. + +// Copyright 2011 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package types + +// under returns the true expanded underlying type. +// If it doesn't exist, the result is Typ[Invalid]. +// under must only be called when a type is known +// to be fully set up. +func under(t Type) Type { + if t, _ := t.(*Named); t != nil { + return t.under() + } + return t.Underlying() +} + +// If t is not a type parameter, coreType returns the underlying type. +// If t is a type parameter, coreType returns the single underlying +// type of all types in its type set if it exists, or nil otherwise. If the +// type set contains only unrestricted and restricted channel types (with +// identical element types), the single underlying type is the restricted +// channel type if the restrictions are always the same, or nil otherwise. +func coreType(t Type) Type { + tpar, _ := t.(*TypeParam) + if tpar == nil { + return under(t) + } + + var su Type + if tpar.underIs(func(u Type) bool { + if u == nil { + return false + } + if su != nil { + u = match(su, u) + if u == nil { + return false + } + } + // su == nil || match(su, u) != nil + su = u + return true + }) { + return su + } + return nil +} + +// coreString is like coreType but also considers []byte +// and strings as identical. In this case, if successful and we saw +// a string, the result is of type (possibly untyped) string. +func coreString(t Type) Type { + tpar, _ := t.(*TypeParam) + if tpar == nil { + return under(t) // string or untyped string + } + + var su Type + hasString := false + if tpar.underIs(func(u Type) bool { + if u == nil { + return false + } + if isString(u) { + u = NewSlice(universeByte) + hasString = true + } + if su != nil { + u = match(su, u) + if u == nil { + return false + } + } + // su == nil || match(su, u) != nil + su = u + return true + }) { + if hasString { + return Typ[String] + } + return su + } + return nil +} + +// If x and y are identical, match returns x. +// If x and y are identical channels but for their direction +// and one of them is unrestricted, match returns the channel +// with the restricted direction. +// In all other cases, match returns nil. +func match(x, y Type) Type { + // Common case: we don't have channels. + if Identical(x, y) { + return x + } + + // We may have channels that differ in direction only. + if x, _ := x.(*Chan); x != nil { + if y, _ := y.(*Chan); y != nil && Identical(x.elem, y.elem) { + // We have channels that differ in direction only. + // If there's an unrestricted channel, select the restricted one. + switch { + case x.dir == SendRecv: + return y + case y.dir == SendRecv: + return x + } + } + } + + // types are different + return nil +} -- 2.50.0