}
func TestTermlistTop(t *testing.T) {
- if !topTermlist.isTop() {
+ if !allTermlist.isAll() {
t.Errorf("topTermlist is not top")
}
}
func TestTermlistString(t *testing.T) {
for _, want := range []string{
"∅",
- "â\8a¤",
+ "ð\9d\93¤",
"int",
"~int",
"∅ ∪ ∅",
- "â\8a¤ â\88ª â\8a¤",
- "∅ ∪ â\8a¤ â\88ª int",
+ "ð\9d\93¤ â\88ª ð\9d\93¤",
+ "∅ ∪ ð\9d\93¤ â\88ª int",
} {
if got := maketl(want).String(); got != want {
t.Errorf("(%v).String() == %v", want, got)
for test, want := range map[string]bool{
"∅": true,
"∅ ∪ ∅": true,
- "∅ ∪ ∅ ∪ â\8a¤": false,
- "â\8a¤": false,
- "â\8a¤ â\88ª int": false,
+ "∅ ∪ ∅ ∪ ð\9d\93¤": false,
+ "ð\9d\93¤": false,
+ "ð\9d\93¤ â\88ª int": false,
} {
xl := maketl(test)
got := xl.isEmpty()
}
}
-func TestTermlistIsTop(t *testing.T) {
+func TestTermlistIsAll(t *testing.T) {
for test, want := range map[string]bool{
"∅": false,
"∅ ∪ ∅": false,
"int ∪ ~string": false,
- "∅ ∪ ∅ ∪ â\8a¤": true,
- "â\8a¤": true,
- "â\8a¤ â\88ª int": true,
+ "∅ ∪ ∅ ∪ ð\9d\93¤": true,
+ "ð\9d\93¤": true,
+ "ð\9d\93¤ â\88ª int": true,
} {
xl := maketl(test)
- got := xl.isTop()
+ got := xl.isAll()
if got != want {
- t.Errorf("(%v).isTop() == %v; want %v", test, got, want)
+ t.Errorf("(%v).isAll() == %v; want %v", test, got, want)
}
}
}
{"∅", "∅"},
{"∅ ∪ ∅", "∅"},
{"∅ ∪ int", "int"},
- {"â\8a¤ â\88ª int", "â\8a¤"},
+ {"ð\9d\93¤ â\88ª int", "ð\9d\93¤"},
{"~int ∪ int", "~int"},
{"int ∪ ~string ∪ int", "int ∪ ~string"},
- {"~int ∪ string ∪ â\8a¤ â\88ª ~string â\88ª int", "â\8a¤"},
+ {"~int ∪ string ∪ ð\9d\93¤ â\88ª ~string â\88ª int", "ð\9d\93¤"},
} {
xl := maketl(test.xl)
got := maketl(test.xl).norm()
for test, want := range map[string]string{
"∅": "nil",
- "â\8a¤": "nil",
+ "ð\9d\93¤": "nil",
"int": "int",
"~int": "int",
"~int ∪ string": "nil",
}{
{"∅", "∅", "∅"},
- {"∅", "â\8a¤", "â\8a¤"},
+ {"∅", "ð\9d\93¤", "ð\9d\93¤"},
{"∅", "int", "int"},
- {"â\8a¤", "~int", "â\8a¤"},
+ {"ð\9d\93¤", "~int", "ð\9d\93¤"},
{"int", "~int", "~int"},
{"int", "string", "int ∪ string"},
{"int ∪ string", "~string", "int ∪ ~string"},
{"~int ∪ string", "~string ∪ int", "~int ∪ ~string"},
{"~int ∪ string ∪ ∅", "~string ∪ int", "~int ∪ ~string"},
- {"~int ∪ string ∪ â\8a¤", "~string â\88ª int", "â\8a¤"},
+ {"~int ∪ string ∪ ð\9d\93¤", "~string â\88ª int", "ð\9d\93¤"},
} {
xl := maketl(test.xl)
yl := maketl(test.yl)
}{
{"∅", "∅", "∅"},
- {"∅", "â\8a¤", "â\88\85"},
+ {"∅", "ð\9d\93¤", "â\88\85"},
{"∅", "int", "∅"},
- {"â\8a¤", "~int", "~int"},
+ {"ð\9d\93¤", "~int", "~int"},
{"int", "~int", "int"},
{"int", "string", "∅"},
{"int ∪ string", "~string", "string"},
{"~int ∪ string", "~string ∪ int", "int ∪ string"},
{"~int ∪ string ∪ ∅", "~string ∪ int", "int ∪ string"},
- {"~int ∪ string ∪ â\8a¤", "~string â\88ª int", "int â\88ª ~string"},
+ {"~int ∪ string ∪ ð\9d\93¤", "~string â\88ª int", "int â\88ª ~string"},
} {
xl := maketl(test.xl)
yl := maketl(test.yl)
want bool
}{
{"∅", "∅", true},
- {"∅", "â\8a¤", false},
- {"â\8a¤", "â\8a¤", true},
- {"â\8a¤ â\88ª int", "â\8a¤", true},
- {"â\8a¤ â\88ª int", "string â\88ª â\8a¤", true},
+ {"∅", "ð\9d\93¤", false},
+ {"ð\9d\93¤", "ð\9d\93¤", true},
+ {"ð\9d\93¤ â\88ª int", "ð\9d\93¤", true},
+ {"ð\9d\93¤ â\88ª int", "string â\88ª ð\9d\93¤", true},
{"int ∪ ~string", "string ∪ int", false},
{"int ∪ ~string ∪ ∅", "string ∪ int ∪ ~string", true},
} {
want bool
}{
{"∅", "int", false},
- {"â\8a¤", "int", true},
+ {"ð\9d\93¤", "int", true},
{"~int", "int", true},
{"int", "string", false},
{"~int", "string", false},
{"int ∪ string", "string", true},
{"~int ∪ string", "int", true},
{"~int ∪ string ∪ ∅", "string", true},
- {"~string ∪ ∅ ∪ â\8a¤", "int", true},
+ {"~string ∪ ∅ ∪ ð\9d\93¤", "int", true},
} {
xl := maketl(test.xl)
yl := testTerm(test.typ).typ
want bool
}{
{"∅", "∅", true},
- {"∅", "â\8a¤", false},
+ {"∅", "ð\9d\93¤", false},
{"∅", "int", false},
- {"â\8a¤", "â\88\85", true},
- {"â\8a¤", "â\8a¤", true},
- {"â\8a¤", "int", true},
- {"â\8a¤", "~int", true},
+ {"ð\9d\93¤", "â\88\85", true},
+ {"ð\9d\93¤", "ð\9d\93¤", true},
+ {"ð\9d\93¤", "int", true},
+ {"ð\9d\93¤", "~int", true},
{"~int", "int", true},
{"~int", "~int", true},
{"int", "~int", false},
{"int ∪ string", "~string", false},
{"~int ∪ string", "int", true},
{"~int ∪ string ∪ ∅", "string", true},
- {"~string ∪ ∅ ∪ â\8a¤", "int", true},
+ {"~string ∪ ∅ ∪ ð\9d\93¤", "int", true},
} {
xl := maketl(test.xl)
y := testTerm(test.typ)
want bool
}{
{"∅", "∅", true},
- {"∅", "â\8a¤", true},
- {"â\8a¤", "â\88\85", false},
- {"â\8a¤", "â\8a¤", true},
+ {"∅", "ð\9d\93¤", true},
+ {"ð\9d\93¤", "â\88\85", false},
+ {"ð\9d\93¤", "ð\9d\93¤", true},
{"int", "int ∪ string", true},
{"~int", "int ∪ string", false},
{"~int", "string ∪ string ∪ int ∪ ~int", true},
{"int ∪ string", "string", false},
{"int ∪ string", "string ∪ int", true},
{"int ∪ ~string", "string ∪ int", false},
- {"int ∪ ~string", "string ∪ int ∪ â\8a¤", true},
+ {"int ∪ ~string", "string ∪ int ∪ ð\9d\93¤", true},
{"int ∪ ~string", "string ∪ int ∪ ∅ ∪ string", false},
} {
xl := maketl(test.xl)
// IsEmpty reports whether type set s is the empty set.
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).
-func (s *_TypeSet) IsTop() bool { return !s.comparable && len(s.methods) == 0 && s.terms.isTop() }
+// IsAll reports whether type set s is the set of all types (corresponding to the empty interface).
+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.
// 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.
func (s *_TypeSet) IsComparable() bool {
- if s.terms.isTop() {
+ if s.terms.isAll() {
return s.comparable
}
return s.is(func(t *term) bool {
switch {
case s.IsEmpty():
return "∅"
- case s.IsTop():
- return "â\8a¤"
+ case s.IsAll():
+ return "ð\9d\93¤"
}
hasMethods := len(s.methods) > 0
// ----------------------------------------------------------------------------
// 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) includes(t Type) bool { return s.terms.includes(t) }
func (s1 *_TypeSet) subsetOf(s2 *_TypeSet) bool { return s1.terms.subsetOf(s2.terms) }
}
// 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.
func computeInterfaceTypeSet(check *Checker, pos token.Pos, ityp *Interface) *_TypeSet {
// have valid interfaces. Mark the interface as complete to avoid
// infinite recursion if the validType check occurs later for some
// 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
// of a method I.m's Func Object of an interface I is the same as that of
}
// collect embedded elements
- var allTerms = topTermlist
+ var allTerms = allTermlist
for i, typ := range ityp.embeddeds {
// The embedding position is nil for imported interfaces
// and also for interface copies after substitution (but
package types
-// 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:
//
// ∅: (*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{true, t} == {t' | under(t') == t} // set of types with underlying type t
//
case x == nil:
return "∅"
case x.typ == nil:
- return "â\8a¤"
+ return "ð\9d\93¤"
case x.tilde:
return "~" + x.typ.String()
default:
case x.typ == nil || y.typ == nil:
return x.typ == y.typ
}
- // ∅ ⊂ x, y ⊂ â\8a¤
+ // ∅ ⊂ x, y ⊂ ð\9d\93¤
return x.tilde == y.tilde && Identical(x.typ, y.typ)
}
case y == nil:
return x, nil // x ∪ ∅ == x
case x.typ == nil:
- return x, nil // â\8a¤ â\88ª y == â\8a¤
+ return x, nil // ð\9d\93¤ â\88ª y == ð\9d\93¤
case y.typ == nil:
- return y, nil // x ∪ â\8a¤ == â\8a¤
+ return y, nil // x ∪ ð\9d\93¤ == ð\9d\93¤
}
- // ∅ ⊂ x, y ⊂ â\8a¤
+ // ∅ ⊂ x, y ⊂ ð\9d\93¤
if x.disjoint(y) {
return x, y // x ∪ y == (x, y) if x ∩ y == ∅
case x == nil || y == nil:
return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅
case x.typ == nil:
- return y // â\8a¤ â\88© y == y
+ return y // ð\9d\93¤ â\88© y == y
case y.typ == nil:
- return x // x ∩ â\8a¤ == x
+ return x // x ∩ ð\9d\93¤ == x
}
- // ∅ ⊂ x, y ⊂ â\8a¤
+ // ∅ ⊂ x, y ⊂ ð\9d\93¤
if x.disjoint(y) {
return nil // x ∩ y == ∅ if x ∩ y == ∅
case x == nil:
return false // t ∈ ∅ == false
case x.typ == nil:
- return true // t ∈ â\8a¤ == true
+ return true // t ∈ ð\9d\93¤ == true
}
- // ∅ ⊂ x ⊂ â\8a¤
+ // ∅ ⊂ x ⊂ ð\9d\93¤
u := t
if x.tilde {
case y == nil:
return false // x ⊆ ∅ == false since x != ∅
case y.typ == nil:
- return true // x ⊆ â\8a¤ == true
+ return true // x ⊆ ð\9d\93¤ == true
case x.typ == nil:
- return false // â\8a¤ â\8a\86 y == false since y != â\8a¤
+ return false // ð\9d\93¤ â\8a\86 y == false since y != ð\9d\93¤
}
- // ∅ ⊂ x, y ⊂ â\8a¤
+ // ∅ ⊂ x, y ⊂ ð\9d\93¤
if x.disjoint(y) {
return false // x ⊆ y == false if x ∩ y == ∅
var testTerms = map[string]*term{
"∅": nil,
- "â\8a¤": {},
+ "ð\9d\93¤": {},
"int": {false, Typ[Int]},
"~int": {true, Typ[Int]},
"string": {false, Typ[String]},
func TestTermEqual(t *testing.T) {
for _, test := range []string{
"∅ ∅ T",
- "â\8a¤ â\8a¤ T",
+ "ð\9d\93¤ ð\9d\93¤ T",
"int int T",
"~int ~int T",
- "∅ â\8a¤ F",
+ "∅ ð\9d\93¤ F",
"∅ int F",
"∅ ~int F",
- "â\8a¤ int F",
- "â\8a¤ ~int F",
+ "ð\9d\93¤ int F",
+ "ð\9d\93¤ ~int F",
"int ~int F",
} {
args := split(test, 3)
func TestTermUnion(t *testing.T) {
for _, test := range []string{
"∅ ∅ ∅ ∅",
- "∅ â\8a¤ â\8a¤ â\88\85",
+ "∅ ð\9d\93¤ ð\9d\93¤ â\88\85",
"∅ int int ∅",
"∅ ~int ~int ∅",
- "â\8a¤ â\8a¤ â\8a¤ â\88\85",
- "â\8a¤ int â\8a¤ â\88\85",
- "â\8a¤ ~int â\8a¤ â\88\85",
+ "ð\9d\93¤ ð\9d\93¤ ð\9d\93¤ â\88\85",
+ "ð\9d\93¤ int ð\9d\93¤ â\88\85",
+ "ð\9d\93¤ ~int ð\9d\93¤ â\88\85",
"int int int ∅",
"int ~int ~int ∅",
"int string int string",
"~int ~string ~int ~string",
// union is symmetric, but the result order isn't - repeat symmetric cases explictly
- "â\8a¤ â\88\85 â\8a¤ â\88\85",
+ "ð\9d\93¤ â\88\85 ð\9d\93¤ â\88\85",
"int ∅ int ∅",
"~int ∅ ~int ∅",
- "int â\8a¤ â\8a¤ â\88\85",
- "~int â\8a¤ â\8a¤ â\88\85",
+ "int ð\9d\93¤ ð\9d\93¤ â\88\85",
+ "~int ð\9d\93¤ ð\9d\93¤ â\88\85",
"~int int ~int ∅",
"string int string int",
"~string int ~string int",
func TestTermIntersection(t *testing.T) {
for _, test := range []string{
"∅ ∅ ∅",
- "∅ â\8a¤ â\88\85",
+ "∅ ð\9d\93¤ â\88\85",
"∅ int ∅",
"∅ ~int ∅",
- "â\8a¤ â\8a¤ â\8a¤",
- "â\8a¤ int int",
- "â\8a¤ ~int ~int",
+ "ð\9d\93¤ ð\9d\93¤ ð\9d\93¤",
+ "ð\9d\93¤ int int",
+ "ð\9d\93¤ ~int ~int",
"int int int",
"int ~int int",
"int string ∅",
func TestTermIncludes(t *testing.T) {
for _, test := range []string{
"∅ int F",
- "â\8a¤ int T",
+ "ð\9d\93¤ int T",
"int int T",
"~int int T",
"string int F",
func TestTermSubsetOf(t *testing.T) {
for _, test := range []string{
"∅ ∅ T",
- "â\8a¤ â\8a¤ T",
+ "ð\9d\93¤ ð\9d\93¤ T",
"int int T",
"~int ~int T",
- "∅ â\8a¤ T",
+ "∅ ð\9d\93¤ T",
"∅ int T",
"∅ ~int T",
- "â\8a¤ int F",
- "â\8a¤ ~int F",
+ "ð\9d\93¤ int F",
+ "ð\9d\93¤ ~int F",
"int ~int T",
} {
args := split(test, 3)