mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.typeparams] cmd/compile/internal/types2: better names for things (cleanup)
- use the symbol π€ (as in π€niverse) instead of β€ to denote the set of all types (for better readabilty, β€ is hard to distinguish from T in some fonts) - use isAll instead of isTop to test for the set of all types - use allTermlist instead of topTermlist to denote the termlist representing all types Change-Id: Idcb0b3398782b38653338e65173c0dbb935e430a Reviewed-on: https://go-review.googlesource.com/c/go/+/339891 Trust: Robert Griesemer <gri@golang.org> Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
110343e4a2
commit
5aac85ad5e
8 changed files with 100 additions and 101 deletions
|
|
@ -174,7 +174,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap
|
||||||
// if iface is comparable, targ must be comparable
|
// if iface is comparable, targ must be comparable
|
||||||
// TODO(gri) the error messages needs to be better, here
|
// TODO(gri) the error messages needs to be better, here
|
||||||
if iface.IsComparable() && !Comparable(targ) {
|
if iface.IsComparable() && !Comparable(targ) {
|
||||||
if tpar := asTypeParam(targ); tpar != nil && tpar.iface().typeSet().IsTop() {
|
if tpar := asTypeParam(targ); tpar != nil && tpar.iface().typeSet().IsAll() {
|
||||||
check.softErrorf(pos, "%s has no constraints", targ)
|
check.softErrorf(pos, "%s has no constraints", targ)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ func (t *Interface) NumMethods() int { return t.typeSet().NumMethods() }
|
||||||
func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
|
func (t *Interface) Method(i int) *Func { return t.typeSet().Method(i) }
|
||||||
|
|
||||||
// Empty reports whether t is the empty interface.
|
// Empty reports whether t is the empty interface.
|
||||||
func (t *Interface) Empty() bool { return t.typeSet().IsTop() }
|
func (t *Interface) Empty() bool { return t.typeSet().IsAll() }
|
||||||
|
|
||||||
// IsComparable reports whether each type in interface t's type set is comparable.
|
// IsComparable reports whether each type in interface t's type set is comparable.
|
||||||
func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable() }
|
func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable() }
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ import "bytes"
|
||||||
// normal form.
|
// normal form.
|
||||||
type termlist []*term
|
type termlist []*term
|
||||||
|
|
||||||
// topTermlist represents the set of all types.
|
// allTermlist represents the set of all types.
|
||||||
// It is in normal form.
|
// It is in normal form.
|
||||||
var topTermlist = termlist{new(term)}
|
var allTermlist = termlist{new(term)}
|
||||||
|
|
||||||
// String prints the termlist exactly (without normalization).
|
// String prints the termlist exactly (without normalization).
|
||||||
func (xl termlist) String() string {
|
func (xl termlist) String() string {
|
||||||
|
|
@ -45,9 +45,9 @@ func (xl termlist) isEmpty() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// isTop reports whether the termlist xl represents the set of all types.
|
// isAll reports whether the termlist xl represents the set of all types.
|
||||||
func (xl termlist) isTop() bool {
|
func (xl termlist) isAll() bool {
|
||||||
// If there's a β€ (top) term, the entire list is β€ (top).
|
// If there's a π€ term, the entire list is π€.
|
||||||
// If the termlist is in normal form, this requires at most
|
// If the termlist is in normal form, this requires at most
|
||||||
// one iteration.
|
// one iteration.
|
||||||
for _, x := range xl {
|
for _, x := range xl {
|
||||||
|
|
@ -74,14 +74,14 @@ func (xl termlist) norm() termlist {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if u1, u2 := xi.union(xj); u2 == nil {
|
if u1, u2 := xi.union(xj); u2 == nil {
|
||||||
// If we encounter a β€ (top) term, the entire
|
// If we encounter a π€ term, the entire list is π€.
|
||||||
// list is β€ (top). Exit early.
|
// Exit early.
|
||||||
// (Note that this is not just an optimization;
|
// (Note that this is not just an optimization;
|
||||||
// if we continue, we may end up with a β€ term
|
// if we continue, we may end up with a π€ term
|
||||||
// and other terms and the result would not be
|
// and other terms and the result would not be
|
||||||
// in normal form.)
|
// in normal form.)
|
||||||
if u1.typ == nil {
|
if u1.typ == nil {
|
||||||
return topTermlist
|
return allTermlist
|
||||||
}
|
}
|
||||||
xi = u1
|
xi = u1
|
||||||
used[j] = true // xj is now unioned into xi - ignore it in future iterations
|
used[j] = true // xj is now unioned into xi - ignore it in future iterations
|
||||||
|
|
@ -92,11 +92,11 @@ func (xl termlist) norm() termlist {
|
||||||
return rl
|
return rl
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the type set represented by xl is specified by a single (non-β€) term,
|
// If the type set represented by xl is specified by a single (non-π€) term,
|
||||||
// structuralType returns that type. Otherwise it returns nil.
|
// structuralType returns that type. Otherwise it returns nil.
|
||||||
func (xl termlist) structuralType() Type {
|
func (xl termlist) structuralType() Type {
|
||||||
if nl := xl.norm(); len(nl) == 1 {
|
if nl := xl.norm(); len(nl) == 1 {
|
||||||
return nl[0].typ // if nl.isTop() then typ is nil, which is ok
|
return nl[0].typ // if nl.isAll() then typ is nil, which is ok
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,20 +21,20 @@ func maketl(s string) termlist {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTermlistTop(t *testing.T) {
|
func TestTermlistTop(t *testing.T) {
|
||||||
if !topTermlist.isTop() {
|
if !allTermlist.isAll() {
|
||||||
t.Errorf("topTermlist is not top")
|
t.Errorf("allTermlist is not the set of all types")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTermlistString(t *testing.T) {
|
func TestTermlistString(t *testing.T) {
|
||||||
for _, want := range []string{
|
for _, want := range []string{
|
||||||
"β
",
|
"β
",
|
||||||
"β€",
|
"π€",
|
||||||
"int",
|
"int",
|
||||||
"~int",
|
"~int",
|
||||||
"β
βͺ β
",
|
"β
βͺ β
",
|
||||||
"β€ βͺ β€",
|
"π€ βͺ π€",
|
||||||
"β
βͺ β€ βͺ int",
|
"β
βͺ π€ βͺ int",
|
||||||
} {
|
} {
|
||||||
if got := maketl(want).String(); got != want {
|
if got := maketl(want).String(); got != want {
|
||||||
t.Errorf("(%v).String() == %v", want, got)
|
t.Errorf("(%v).String() == %v", want, got)
|
||||||
|
|
@ -46,9 +46,9 @@ func TestTermlistIsEmpty(t *testing.T) {
|
||||||
for test, want := range map[string]bool{
|
for test, want := range map[string]bool{
|
||||||
"β
": true,
|
"β
": true,
|
||||||
"β
βͺ β
": true,
|
"β
βͺ β
": true,
|
||||||
"β
βͺ β
βͺ β€": false,
|
"β
βͺ β
βͺ π€": false,
|
||||||
"β€": false,
|
"π€": false,
|
||||||
"β€ βͺ int": false,
|
"π€ βͺ int": false,
|
||||||
} {
|
} {
|
||||||
xl := maketl(test)
|
xl := maketl(test)
|
||||||
got := xl.isEmpty()
|
got := xl.isEmpty()
|
||||||
|
|
@ -58,19 +58,19 @@ func TestTermlistIsEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTermlistIsTop(t *testing.T) {
|
func TestTermlistIsAll(t *testing.T) {
|
||||||
for test, want := range map[string]bool{
|
for test, want := range map[string]bool{
|
||||||
"β
": false,
|
"β
": false,
|
||||||
"β
βͺ β
": false,
|
"β
βͺ β
": false,
|
||||||
"int βͺ ~string": false,
|
"int βͺ ~string": false,
|
||||||
"β
βͺ β
βͺ β€": true,
|
"β
βͺ β
βͺ π€": true,
|
||||||
"β€": true,
|
"π€": true,
|
||||||
"β€ βͺ int": true,
|
"π€ βͺ int": true,
|
||||||
} {
|
} {
|
||||||
xl := maketl(test)
|
xl := maketl(test)
|
||||||
got := xl.isTop()
|
got := xl.isAll()
|
||||||
if got != want {
|
if got != want {
|
||||||
t.Errorf("(%v).isTop() == %v; want %v", test, got, want)
|
t.Errorf("(%v).isAll() == %v; want %v", test, got, want)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -82,10 +82,10 @@ func TestTermlistNorm(t *testing.T) {
|
||||||
{"β
", "β
"},
|
{"β
", "β
"},
|
||||||
{"β
βͺ β
", "β
"},
|
{"β
βͺ β
", "β
"},
|
||||||
{"β
βͺ int", "int"},
|
{"β
βͺ int", "int"},
|
||||||
{"β€ βͺ int", "β€"},
|
{"π€ βͺ int", "π€"},
|
||||||
{"~int βͺ int", "~int"},
|
{"~int βͺ int", "~int"},
|
||||||
{"int βͺ ~string βͺ int", "int βͺ ~string"},
|
{"int βͺ ~string βͺ int", "int βͺ ~string"},
|
||||||
{"~int βͺ string βͺ β€ βͺ ~string βͺ int", "β€"},
|
{"~int βͺ string βͺ π€ βͺ ~string βͺ int", "π€"},
|
||||||
} {
|
} {
|
||||||
xl := maketl(test.xl)
|
xl := maketl(test.xl)
|
||||||
got := maketl(test.xl).norm()
|
got := maketl(test.xl).norm()
|
||||||
|
|
@ -106,7 +106,7 @@ func TestTermlistStructuralType(t *testing.T) {
|
||||||
|
|
||||||
for test, want := range map[string]string{
|
for test, want := range map[string]string{
|
||||||
"β
": "nil",
|
"β
": "nil",
|
||||||
"β€": "nil",
|
"π€": "nil",
|
||||||
"int": "int",
|
"int": "int",
|
||||||
"~int": "int",
|
"~int": "int",
|
||||||
"~int βͺ string": "nil",
|
"~int βͺ string": "nil",
|
||||||
|
|
@ -128,15 +128,15 @@ func TestTermlistUnion(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
|
|
||||||
{"β
", "β
", "β
"},
|
{"β
", "β
", "β
"},
|
||||||
{"β
", "β€", "β€"},
|
{"β
", "π€", "π€"},
|
||||||
{"β
", "int", "int"},
|
{"β
", "int", "int"},
|
||||||
{"β€", "~int", "β€"},
|
{"π€", "~int", "π€"},
|
||||||
{"int", "~int", "~int"},
|
{"int", "~int", "~int"},
|
||||||
{"int", "string", "int βͺ string"},
|
{"int", "string", "int βͺ string"},
|
||||||
{"int βͺ string", "~string", "int βͺ ~string"},
|
{"int βͺ string", "~string", "int βͺ ~string"},
|
||||||
{"~int βͺ string", "~string βͺ int", "~int βͺ ~string"},
|
{"~int βͺ string", "~string βͺ int", "~int βͺ ~string"},
|
||||||
{"~int βͺ string βͺ β
", "~string βͺ int", "~int βͺ ~string"},
|
{"~int βͺ string βͺ β
", "~string βͺ int", "~int βͺ ~string"},
|
||||||
{"~int βͺ string βͺ β€", "~string βͺ int", "β€"},
|
{"~int βͺ string βͺ π€", "~string βͺ int", "π€"},
|
||||||
} {
|
} {
|
||||||
xl := maketl(test.xl)
|
xl := maketl(test.xl)
|
||||||
yl := maketl(test.yl)
|
yl := maketl(test.yl)
|
||||||
|
|
@ -153,15 +153,15 @@ func TestTermlistIntersect(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
|
|
||||||
{"β
", "β
", "β
"},
|
{"β
", "β
", "β
"},
|
||||||
{"β
", "β€", "β
"},
|
{"β
", "π€", "β
"},
|
||||||
{"β
", "int", "β
"},
|
{"β
", "int", "β
"},
|
||||||
{"β€", "~int", "~int"},
|
{"π€", "~int", "~int"},
|
||||||
{"int", "~int", "int"},
|
{"int", "~int", "int"},
|
||||||
{"int", "string", "β
"},
|
{"int", "string", "β
"},
|
||||||
{"int βͺ string", "~string", "string"},
|
{"int βͺ string", "~string", "string"},
|
||||||
{"~int βͺ string", "~string βͺ int", "int βͺ string"},
|
{"~int βͺ string", "~string βͺ int", "int βͺ string"},
|
||||||
{"~int βͺ string βͺ β
", "~string βͺ int", "int βͺ string"},
|
{"~int βͺ string βͺ β
", "~string βͺ int", "int βͺ string"},
|
||||||
{"~int βͺ string βͺ β€", "~string βͺ int", "int βͺ ~string"},
|
{"~int βͺ string βͺ π€", "~string βͺ int", "int βͺ ~string"},
|
||||||
} {
|
} {
|
||||||
xl := maketl(test.xl)
|
xl := maketl(test.xl)
|
||||||
yl := maketl(test.yl)
|
yl := maketl(test.yl)
|
||||||
|
|
@ -178,10 +178,10 @@ func TestTermlistEqual(t *testing.T) {
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"β
", "β
", true},
|
{"β
", "β
", true},
|
||||||
{"β
", "β€", false},
|
{"β
", "π€", false},
|
||||||
{"β€", "β€", true},
|
{"π€", "π€", true},
|
||||||
{"β€ βͺ int", "β€", true},
|
{"π€ βͺ int", "π€", true},
|
||||||
{"β€ βͺ int", "string βͺ β€", true},
|
{"π€ βͺ int", "string βͺ π€", true},
|
||||||
{"int βͺ ~string", "string βͺ int", false},
|
{"int βͺ ~string", "string βͺ int", false},
|
||||||
{"int βͺ ~string βͺ β
", "string βͺ int βͺ ~string", true},
|
{"int βͺ ~string βͺ β
", "string βͺ int βͺ ~string", true},
|
||||||
} {
|
} {
|
||||||
|
|
@ -200,14 +200,14 @@ func TestTermlistIncludes(t *testing.T) {
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"β
", "int", false},
|
{"β
", "int", false},
|
||||||
{"β€", "int", true},
|
{"π€", "int", true},
|
||||||
{"~int", "int", true},
|
{"~int", "int", true},
|
||||||
{"int", "string", false},
|
{"int", "string", false},
|
||||||
{"~int", "string", false},
|
{"~int", "string", false},
|
||||||
{"int βͺ string", "string", true},
|
{"int βͺ string", "string", true},
|
||||||
{"~int βͺ string", "int", true},
|
{"~int βͺ string", "int", true},
|
||||||
{"~int βͺ string βͺ β
", "string", true},
|
{"~int βͺ string βͺ β
", "string", true},
|
||||||
{"~string βͺ β
βͺ β€", "int", true},
|
{"~string βͺ β
βͺ π€", "int", true},
|
||||||
} {
|
} {
|
||||||
xl := maketl(test.xl)
|
xl := maketl(test.xl)
|
||||||
yl := testTerm(test.typ).typ
|
yl := testTerm(test.typ).typ
|
||||||
|
|
@ -224,12 +224,12 @@ func TestTermlistSupersetOf(t *testing.T) {
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"β
", "β
", true},
|
{"β
", "β
", true},
|
||||||
{"β
", "β€", false},
|
{"β
", "π€", false},
|
||||||
{"β
", "int", false},
|
{"β
", "int", false},
|
||||||
{"β€", "β
", true},
|
{"π€", "β
", true},
|
||||||
{"β€", "β€", true},
|
{"π€", "π€", true},
|
||||||
{"β€", "int", true},
|
{"π€", "int", true},
|
||||||
{"β€", "~int", true},
|
{"π€", "~int", true},
|
||||||
{"~int", "int", true},
|
{"~int", "int", true},
|
||||||
{"~int", "~int", true},
|
{"~int", "~int", true},
|
||||||
{"int", "~int", false},
|
{"int", "~int", false},
|
||||||
|
|
@ -239,7 +239,7 @@ func TestTermlistSupersetOf(t *testing.T) {
|
||||||
{"int βͺ string", "~string", false},
|
{"int βͺ string", "~string", false},
|
||||||
{"~int βͺ string", "int", true},
|
{"~int βͺ string", "int", true},
|
||||||
{"~int βͺ string βͺ β
", "string", true},
|
{"~int βͺ string βͺ β
", "string", true},
|
||||||
{"~string βͺ β
βͺ β€", "int", true},
|
{"~string βͺ β
βͺ π€", "int", true},
|
||||||
} {
|
} {
|
||||||
xl := maketl(test.xl)
|
xl := maketl(test.xl)
|
||||||
y := testTerm(test.typ)
|
y := testTerm(test.typ)
|
||||||
|
|
@ -256,16 +256,16 @@ func TestTermlistSubsetOf(t *testing.T) {
|
||||||
want bool
|
want bool
|
||||||
}{
|
}{
|
||||||
{"β
", "β
", true},
|
{"β
", "β
", true},
|
||||||
{"β
", "β€", true},
|
{"β
", "π€", true},
|
||||||
{"β€", "β
", false},
|
{"π€", "β
", false},
|
||||||
{"β€", "β€", true},
|
{"π€", "π€", true},
|
||||||
{"int", "int βͺ string", true},
|
{"int", "int βͺ string", true},
|
||||||
{"~int", "int βͺ string", false},
|
{"~int", "int βͺ string", false},
|
||||||
{"~int", "string βͺ string βͺ int βͺ ~int", true},
|
{"~int", "string βͺ string βͺ int βͺ ~int", true},
|
||||||
{"int βͺ string", "string", false},
|
{"int βͺ string", "string", false},
|
||||||
{"int βͺ string", "string βͺ int", true},
|
{"int βͺ string", "string βͺ int", true},
|
||||||
{"int βͺ ~string", "string βͺ int", false},
|
{"int βͺ ~string", "string βͺ int", false},
|
||||||
{"int βͺ ~string", "string βͺ int βͺ β€", true},
|
{"int βͺ ~string", "string βͺ int βͺ π€", true},
|
||||||
{"int βͺ ~string", "string βͺ int βͺ β
βͺ string", false},
|
{"int βͺ ~string", "string βͺ int βͺ β
βͺ string", false},
|
||||||
} {
|
} {
|
||||||
xl := maketl(test.xl)
|
xl := maketl(test.xl)
|
||||||
|
|
|
||||||
|
|
@ -25,17 +25,19 @@ type TypeSet struct {
|
||||||
// IsEmpty reports whether type set s is the empty set.
|
// IsEmpty reports whether type set s is the empty set.
|
||||||
func (s *TypeSet) IsEmpty() bool { return s.terms.isEmpty() }
|
func (s *TypeSet) IsEmpty() bool { return s.terms.isEmpty() }
|
||||||
|
|
||||||
// IsTop reports whether type set s is the set of all types (corresponding to the empty interface).
|
// IsAll reports whether type set s is the set of all types (corresponding to the empty interface).
|
||||||
func (s *TypeSet) IsTop() bool { return !s.comparable && len(s.methods) == 0 && s.terms.isTop() }
|
func (s *TypeSet) IsAll() bool {
|
||||||
|
return !s.comparable && len(s.methods) == 0 && s.terms.isAll()
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(gri) IsMethodSet is not a great name for this predicate. Find a better one.
|
// TODO(gri) IsMethodSet is not a great name for this predicate. Find a better one.
|
||||||
|
|
||||||
// IsMethodSet reports whether the type set s is described by a single set of methods.
|
// IsMethodSet reports whether the type set s is described by a single set of methods.
|
||||||
func (s *TypeSet) IsMethodSet() bool { return !s.comparable && s.terms.isTop() }
|
func (s *TypeSet) IsMethodSet() bool { return !s.comparable && s.terms.isAll() }
|
||||||
|
|
||||||
// IsComparable reports whether each type in the set is comparable.
|
// IsComparable reports whether each type in the set is comparable.
|
||||||
func (s *TypeSet) IsComparable() bool {
|
func (s *TypeSet) IsComparable() bool {
|
||||||
if s.terms.isTop() {
|
if s.terms.isAll() {
|
||||||
return s.comparable
|
return s.comparable
|
||||||
}
|
}
|
||||||
return s.is(func(t *term) bool {
|
return s.is(func(t *term) bool {
|
||||||
|
|
@ -67,8 +69,8 @@ func (s *TypeSet) String() string {
|
||||||
switch {
|
switch {
|
||||||
case s.IsEmpty():
|
case s.IsEmpty():
|
||||||
return "β
"
|
return "β
"
|
||||||
case s.IsTop():
|
case s.IsAll():
|
||||||
return "β€"
|
return "π€"
|
||||||
}
|
}
|
||||||
|
|
||||||
hasMethods := len(s.methods) > 0
|
hasMethods := len(s.methods) > 0
|
||||||
|
|
@ -103,7 +105,7 @@ func (s *TypeSet) String() string {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Implementation
|
// Implementation
|
||||||
|
|
||||||
func (s *TypeSet) hasTerms() bool { return !s.terms.isTop() }
|
func (s *TypeSet) hasTerms() bool { return !s.terms.isAll() }
|
||||||
func (s *TypeSet) structuralType() Type { return s.terms.structuralType() }
|
func (s *TypeSet) structuralType() Type { return s.terms.structuralType() }
|
||||||
func (s *TypeSet) includes(t Type) bool { return s.terms.includes(t) }
|
func (s *TypeSet) includes(t Type) bool { return s.terms.includes(t) }
|
||||||
func (s1 *TypeSet) subsetOf(s2 *TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
|
func (s1 *TypeSet) subsetOf(s2 *TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
|
||||||
|
|
@ -156,7 +158,7 @@ func (s *TypeSet) underIs(f func(Type) bool) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// topTypeSet may be used as type set for the empty interface.
|
// topTypeSet may be used as type set for the empty interface.
|
||||||
var topTypeSet = TypeSet{terms: topTermlist}
|
var topTypeSet = TypeSet{terms: allTermlist}
|
||||||
|
|
||||||
// computeInterfaceTypeSet may be called with check == nil.
|
// computeInterfaceTypeSet may be called with check == nil.
|
||||||
func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *TypeSet {
|
func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *TypeSet {
|
||||||
|
|
@ -195,7 +197,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *T
|
||||||
// have valid interfaces. Mark the interface as complete to avoid
|
// have valid interfaces. Mark the interface as complete to avoid
|
||||||
// infinite recursion if the validType check occurs later for some
|
// infinite recursion if the validType check occurs later for some
|
||||||
// reason.
|
// reason.
|
||||||
ityp.tset = &TypeSet{terms: topTermlist} // TODO(gri) is this sufficient?
|
ityp.tset = &TypeSet{terms: allTermlist} // TODO(gri) is this sufficient?
|
||||||
|
|
||||||
// Methods of embedded interfaces are collected unchanged; i.e., the identity
|
// Methods of embedded interfaces are collected unchanged; i.e., the identity
|
||||||
// of a method I.m's Func Object of an interface I is the same as that of
|
// of a method I.m's Func Object of an interface I is the same as that of
|
||||||
|
|
@ -256,7 +258,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *T
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect embedded elements
|
// collect embedded elements
|
||||||
var allTerms = topTermlist
|
var allTerms = allTermlist
|
||||||
for i, typ := range ityp.embeddeds {
|
for i, typ := range ityp.embeddeds {
|
||||||
// The embedding position is nil for imported interfaces
|
// The embedding position is nil for imported interfaces
|
||||||
// and also for interface copies after substitution (but
|
// and also for interface copies after substitution (but
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,10 @@
|
||||||
|
|
||||||
package types2
|
package types2
|
||||||
|
|
||||||
// TODO(gri) use a different symbol instead of β€ for the set of all types
|
|
||||||
// (β€ is hard to distinguish from T in some fonts)
|
|
||||||
|
|
||||||
// A term describes elementary type sets:
|
// A term describes elementary type sets:
|
||||||
//
|
//
|
||||||
// β
: (*term)(nil) == β
// set of no types (empty set)
|
// β
: (*term)(nil) == β
// set of no types (empty set)
|
||||||
// β€: &term{} == β€ // set of all types
|
// π€: &term{} == π€ // set of all types (π€niverse)
|
||||||
// T: &term{false, T} == {T} // set of type T
|
// T: &term{false, T} == {T} // set of type T
|
||||||
// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
|
// ~t: &term{true, t} == {t' | under(t') == t} // set of types with underlying type t
|
||||||
//
|
//
|
||||||
|
|
@ -24,7 +21,7 @@ func (x *term) String() string {
|
||||||
case x == nil:
|
case x == nil:
|
||||||
return "β
"
|
return "β
"
|
||||||
case x.typ == nil:
|
case x.typ == nil:
|
||||||
return "β€"
|
return "π€"
|
||||||
case x.tilde:
|
case x.tilde:
|
||||||
return "~" + x.typ.String()
|
return "~" + x.typ.String()
|
||||||
default:
|
default:
|
||||||
|
|
@ -41,7 +38,7 @@ func (x *term) equal(y *term) bool {
|
||||||
case x.typ == nil || y.typ == nil:
|
case x.typ == nil || y.typ == nil:
|
||||||
return x.typ == y.typ
|
return x.typ == y.typ
|
||||||
}
|
}
|
||||||
// β
β x, y β β€
|
// β
β x, y β π€
|
||||||
|
|
||||||
return x.tilde == y.tilde && Identical(x.typ, y.typ)
|
return x.tilde == y.tilde && Identical(x.typ, y.typ)
|
||||||
}
|
}
|
||||||
|
|
@ -57,11 +54,11 @@ func (x *term) union(y *term) (_, _ *term) {
|
||||||
case y == nil:
|
case y == nil:
|
||||||
return x, nil // x βͺ β
== x
|
return x, nil // x βͺ β
== x
|
||||||
case x.typ == nil:
|
case x.typ == nil:
|
||||||
return x, nil // β€ βͺ y == β€
|
return x, nil // π€ βͺ y == π€
|
||||||
case y.typ == nil:
|
case y.typ == nil:
|
||||||
return y, nil // x βͺ β€ == β€
|
return y, nil // x βͺ π€ == π€
|
||||||
}
|
}
|
||||||
// β
β x, y β β€
|
// β
β x, y β π€
|
||||||
|
|
||||||
if x.disjoint(y) {
|
if x.disjoint(y) {
|
||||||
return x, y // x βͺ y == (x, y) if x β© y == β
|
return x, y // x βͺ y == (x, y) if x β© y == β
|
||||||
|
|
@ -85,11 +82,11 @@ func (x *term) intersect(y *term) *term {
|
||||||
case x == nil || y == nil:
|
case x == nil || y == nil:
|
||||||
return nil // β
β© y == β
and β© β
== β
|
return nil // β
β© y == β
and β© β
== β
|
||||||
case x.typ == nil:
|
case x.typ == nil:
|
||||||
return y // β€ β© y == y
|
return y // π€ β© y == y
|
||||||
case y.typ == nil:
|
case y.typ == nil:
|
||||||
return x // x β© β€ == x
|
return x // x β© π€ == x
|
||||||
}
|
}
|
||||||
// β
β x, y β β€
|
// β
β x, y β π€
|
||||||
|
|
||||||
if x.disjoint(y) {
|
if x.disjoint(y) {
|
||||||
return nil // x β© y == β
if x β© y == β
|
return nil // x β© y == β
if x β© y == β
|
||||||
|
|
@ -113,9 +110,9 @@ func (x *term) includes(t Type) bool {
|
||||||
case x == nil:
|
case x == nil:
|
||||||
return false // t β β
== false
|
return false // t β β
== false
|
||||||
case x.typ == nil:
|
case x.typ == nil:
|
||||||
return true // t β β€ == true
|
return true // t β π€ == true
|
||||||
}
|
}
|
||||||
// β
β x β β€
|
// β
β x β π€
|
||||||
|
|
||||||
u := t
|
u := t
|
||||||
if x.tilde {
|
if x.tilde {
|
||||||
|
|
@ -133,11 +130,11 @@ func (x *term) subsetOf(y *term) bool {
|
||||||
case y == nil:
|
case y == nil:
|
||||||
return false // x β β
== false since x != β
|
return false // x β β
== false since x != β
|
||||||
case y.typ == nil:
|
case y.typ == nil:
|
||||||
return true // x β β€ == true
|
return true // x β π€ == true
|
||||||
case x.typ == nil:
|
case x.typ == nil:
|
||||||
return false // β€ β y == false since y != β€
|
return false // π€ β y == false since y != π€
|
||||||
}
|
}
|
||||||
// β
β x, y β β€
|
// β
β x, y β π€
|
||||||
|
|
||||||
if x.disjoint(y) {
|
if x.disjoint(y) {
|
||||||
return false // x β y == false if x β© y == β
|
return false // x β y == false if x β© y == β
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
|
|
||||||
var testTerms = map[string]*term{
|
var testTerms = map[string]*term{
|
||||||
"β
": nil,
|
"β
": nil,
|
||||||
"β€": {},
|
"π€": {},
|
||||||
"int": {false, Typ[Int]},
|
"int": {false, Typ[Int]},
|
||||||
"~int": {true, Typ[Int]},
|
"~int": {true, Typ[Int]},
|
||||||
"string": {false, Typ[String]},
|
"string": {false, Typ[String]},
|
||||||
|
|
@ -46,14 +46,14 @@ func testTerm(name string) *term {
|
||||||
func TestTermEqual(t *testing.T) {
|
func TestTermEqual(t *testing.T) {
|
||||||
for _, test := range []string{
|
for _, test := range []string{
|
||||||
"β
β
T",
|
"β
β
T",
|
||||||
"β€ β€ T",
|
"π€ π€ T",
|
||||||
"int int T",
|
"int int T",
|
||||||
"~int ~int T",
|
"~int ~int T",
|
||||||
"β
β€ F",
|
"β
π€ F",
|
||||||
"β
int F",
|
"β
int F",
|
||||||
"β
~int F",
|
"β
~int F",
|
||||||
"β€ int F",
|
"π€ int F",
|
||||||
"β€ ~int F",
|
"π€ ~int F",
|
||||||
"int ~int F",
|
"int ~int F",
|
||||||
} {
|
} {
|
||||||
args := split(test, 3)
|
args := split(test, 3)
|
||||||
|
|
@ -74,12 +74,12 @@ func TestTermEqual(t *testing.T) {
|
||||||
func TestTermUnion(t *testing.T) {
|
func TestTermUnion(t *testing.T) {
|
||||||
for _, test := range []string{
|
for _, test := range []string{
|
||||||
"β
β
β
β
",
|
"β
β
β
β
",
|
||||||
"β
β€ β€ β
",
|
"β
π€ π€ β
",
|
||||||
"β
int int β
",
|
"β
int int β
",
|
||||||
"β
~int ~int β
",
|
"β
~int ~int β
",
|
||||||
"β€ β€ β€ β
",
|
"π€ π€ π€ β
",
|
||||||
"β€ int β€ β
",
|
"π€ int π€ β
",
|
||||||
"β€ ~int β€ β
",
|
"π€ ~int π€ β
",
|
||||||
"int int int β
",
|
"int int int β
",
|
||||||
"int ~int ~int β
",
|
"int ~int ~int β
",
|
||||||
"int string int string",
|
"int string int string",
|
||||||
|
|
@ -87,11 +87,11 @@ func TestTermUnion(t *testing.T) {
|
||||||
"~int ~string ~int ~string",
|
"~int ~string ~int ~string",
|
||||||
|
|
||||||
// union is symmetric, but the result order isn't - repeat symmetric cases explictly
|
// union is symmetric, but the result order isn't - repeat symmetric cases explictly
|
||||||
"β€ β
β€ β
",
|
"π€ β
π€ β
",
|
||||||
"int β
int β
",
|
"int β
int β
",
|
||||||
"~int β
~int β
",
|
"~int β
~int β
",
|
||||||
"int β€ β€ β
",
|
"int π€ π€ β
",
|
||||||
"~int β€ β€ β
",
|
"~int π€ π€ β
",
|
||||||
"~int int ~int β
",
|
"~int int ~int β
",
|
||||||
"string int string int",
|
"string int string int",
|
||||||
"~string int ~string int",
|
"~string int ~string int",
|
||||||
|
|
@ -111,12 +111,12 @@ func TestTermUnion(t *testing.T) {
|
||||||
func TestTermIntersection(t *testing.T) {
|
func TestTermIntersection(t *testing.T) {
|
||||||
for _, test := range []string{
|
for _, test := range []string{
|
||||||
"β
β
β
",
|
"β
β
β
",
|
||||||
"β
β€ β
",
|
"β
π€ β
",
|
||||||
"β
int β
",
|
"β
int β
",
|
||||||
"β
~int β
",
|
"β
~int β
",
|
||||||
"β€ β€ β€",
|
"π€ π€ π€",
|
||||||
"β€ int int",
|
"π€ int int",
|
||||||
"β€ ~int ~int",
|
"π€ ~int ~int",
|
||||||
"int int int",
|
"int int int",
|
||||||
"int ~int int",
|
"int ~int int",
|
||||||
"int string β
",
|
"int string β
",
|
||||||
|
|
@ -141,7 +141,7 @@ func TestTermIntersection(t *testing.T) {
|
||||||
func TestTermIncludes(t *testing.T) {
|
func TestTermIncludes(t *testing.T) {
|
||||||
for _, test := range []string{
|
for _, test := range []string{
|
||||||
"β
int F",
|
"β
int F",
|
||||||
"β€ int T",
|
"π€ int T",
|
||||||
"int int T",
|
"int int T",
|
||||||
"~int int T",
|
"~int int T",
|
||||||
"string int F",
|
"string int F",
|
||||||
|
|
@ -160,14 +160,14 @@ func TestTermIncludes(t *testing.T) {
|
||||||
func TestTermSubsetOf(t *testing.T) {
|
func TestTermSubsetOf(t *testing.T) {
|
||||||
for _, test := range []string{
|
for _, test := range []string{
|
||||||
"β
β
T",
|
"β
β
T",
|
||||||
"β€ β€ T",
|
"π€ π€ T",
|
||||||
"int int T",
|
"int int T",
|
||||||
"~int ~int T",
|
"~int ~int T",
|
||||||
"β
β€ T",
|
"β
π€ T",
|
||||||
"β
int T",
|
"β
int T",
|
||||||
"β
~int T",
|
"β
~int T",
|
||||||
"β€ int F",
|
"π€ int F",
|
||||||
"β€ ~int F",
|
"π€ ~int F",
|
||||||
"int ~int T",
|
"int ~int T",
|
||||||
} {
|
} {
|
||||||
args := split(test, 3)
|
args := split(test, 3)
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ func defPredeclaredTypes() {
|
||||||
{
|
{
|
||||||
obj := NewTypeName(nopos, nil, "comparable", nil)
|
obj := NewTypeName(nopos, nil, "comparable", nil)
|
||||||
obj.setColor(black)
|
obj.setColor(black)
|
||||||
ityp := &Interface{obj, nil, nil, nil, true, &TypeSet{true, nil, topTermlist}}
|
ityp := &Interface{obj, nil, nil, nil, true, &TypeSet{true, nil, allTermlist}}
|
||||||
NewNamed(obj, ityp, nil)
|
NewNamed(obj, ityp, nil)
|
||||||
def(obj)
|
def(obj)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loadingβ¦
Add table
Add a link
Reference in a new issue