From 5aac85ad5ebfa9c2ecb01a3292bcf3513d876d7a Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 4 Aug 2021 15:18:37 -0700 Subject: [PATCH] [dev.typeparams] cmd/compile/internal/types2: better names for things (cleanup) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - 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 Run-TryBot: Robert Griesemer TryBot-Result: Go Bot Reviewed-by: Robert Findley --- .../compile/internal/types2/instantiate.go | 2 +- src/cmd/compile/internal/types2/interface.go | 2 +- src/cmd/compile/internal/types2/termlist.go | 22 +++--- .../compile/internal/types2/termlist_test.go | 78 +++++++++---------- src/cmd/compile/internal/types2/typeset.go | 22 +++--- src/cmd/compile/internal/types2/typeterm.go | 31 ++++---- .../compile/internal/types2/typeterm_test.go | 42 +++++----- src/cmd/compile/internal/types2/universe.go | 2 +- 8 files changed, 100 insertions(+), 101 deletions(-) diff --git a/src/cmd/compile/internal/types2/instantiate.go b/src/cmd/compile/internal/types2/instantiate.go index b7ea193a06..0bb4ac956b 100644 --- a/src/cmd/compile/internal/types2/instantiate.go +++ b/src/cmd/compile/internal/types2/instantiate.go @@ -174,7 +174,7 @@ func (check *Checker) satisfies(pos syntax.Pos, targ Type, tpar *TypeParam, smap // if iface is comparable, targ must be comparable // TODO(gri) the error messages needs to be better, here 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) return false } diff --git a/src/cmd/compile/internal/types2/interface.go b/src/cmd/compile/internal/types2/interface.go index aa7d0b05a0..f763f8ff44 100644 --- a/src/cmd/compile/internal/types2/interface.go +++ b/src/cmd/compile/internal/types2/interface.go @@ -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) } // 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. func (t *Interface) IsComparable() bool { return t.typeSet().IsComparable() } diff --git a/src/cmd/compile/internal/types2/termlist.go b/src/cmd/compile/internal/types2/termlist.go index 07056edd97..378ba6b8f4 100644 --- a/src/cmd/compile/internal/types2/termlist.go +++ b/src/cmd/compile/internal/types2/termlist.go @@ -13,9 +13,9 @@ import "bytes" // normal form. type termlist []*term -// topTermlist represents the set of all types. +// allTermlist represents the set of all types. // It is in normal form. -var topTermlist = termlist{new(term)} +var allTermlist = termlist{new(term)} // String prints the termlist exactly (without normalization). func (xl termlist) String() string { @@ -45,9 +45,9 @@ func (xl termlist) isEmpty() bool { return true } -// isTop reports whether the termlist xl represents the set of all types. -func (xl termlist) isTop() bool { - // If there's a ⊤ (top) term, the entire list is ⊤ (top). +// isAll reports whether the termlist xl represents the set of all types. +func (xl termlist) isAll() bool { + // If there's a 𝓤 term, the entire list is 𝓤. // If the termlist is in normal form, this requires at most // one iteration. for _, x := range xl { @@ -74,14 +74,14 @@ func (xl termlist) norm() termlist { continue } if u1, u2 := xi.union(xj); u2 == nil { - // If we encounter a ⊤ (top) term, the entire - // list is ⊤ (top). Exit early. + // If we encounter a 𝓤 term, the entire list is 𝓤. + // Exit early. // (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 // in normal form.) if u1.typ == nil { - return topTermlist + return allTermlist } xi = u1 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 } -// 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. func (xl termlist) structuralType() Type { 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 } diff --git a/src/cmd/compile/internal/types2/termlist_test.go b/src/cmd/compile/internal/types2/termlist_test.go index c36baeb86f..706b4c9756 100644 --- a/src/cmd/compile/internal/types2/termlist_test.go +++ b/src/cmd/compile/internal/types2/termlist_test.go @@ -21,20 +21,20 @@ func maketl(s string) termlist { } func TestTermlistTop(t *testing.T) { - if !topTermlist.isTop() { - t.Errorf("topTermlist is not top") + if !allTermlist.isAll() { + t.Errorf("allTermlist is not the set of all types") } } func TestTermlistString(t *testing.T) { for _, want := range []string{ "∅", - "⊤", + "𝓤", "int", "~int", "∅ ∪ ∅", - "⊤ ∪ ⊤", - "∅ ∪ ⊤ ∪ int", + "𝓤 ∪ 𝓤", + "∅ ∪ 𝓤 ∪ int", } { if got := maketl(want).String(); got != want { t.Errorf("(%v).String() == %v", want, got) @@ -46,9 +46,9 @@ func TestTermlistIsEmpty(t *testing.T) { for test, want := range map[string]bool{ "∅": true, "∅ ∪ ∅": true, - "∅ ∪ ∅ ∪ ⊤": false, - "⊤": false, - "⊤ ∪ int": false, + "∅ ∪ ∅ ∪ 𝓤": false, + "𝓤": false, + "𝓤 ∪ int": false, } { xl := maketl(test) 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{ "∅": false, "∅ ∪ ∅": false, "int ∪ ~string": false, - "∅ ∪ ∅ ∪ ⊤": true, - "⊤": true, - "⊤ ∪ int": true, + "∅ ∪ ∅ ∪ 𝓤": true, + "𝓤": true, + "𝓤 ∪ 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) } } } @@ -82,10 +82,10 @@ func TestTermlistNorm(t *testing.T) { {"∅", "∅"}, {"∅ ∪ ∅", "∅"}, {"∅ ∪ int", "int"}, - {"⊤ ∪ int", "⊤"}, + {"𝓤 ∪ int", "𝓤"}, {"~int ∪ int", "~int"}, {"int ∪ ~string ∪ int", "int ∪ ~string"}, - {"~int ∪ string ∪ ⊤ ∪ ~string ∪ int", "⊤"}, + {"~int ∪ string ∪ 𝓤 ∪ ~string ∪ int", "𝓤"}, } { xl := maketl(test.xl) got := maketl(test.xl).norm() @@ -106,7 +106,7 @@ func TestTermlistStructuralType(t *testing.T) { for test, want := range map[string]string{ "∅": "nil", - "⊤": "nil", + "𝓤": "nil", "int": "int", "~int": "int", "~int ∪ string": "nil", @@ -128,15 +128,15 @@ func TestTermlistUnion(t *testing.T) { }{ {"∅", "∅", "∅"}, - {"∅", "⊤", "⊤"}, + {"∅", "𝓤", "𝓤"}, {"∅", "int", "int"}, - {"⊤", "~int", "⊤"}, + {"𝓤", "~int", "𝓤"}, {"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 ∪ ⊤", "~string ∪ int", "⊤"}, + {"~int ∪ string ∪ 𝓤", "~string ∪ int", "𝓤"}, } { xl := maketl(test.xl) yl := maketl(test.yl) @@ -153,15 +153,15 @@ func TestTermlistIntersect(t *testing.T) { }{ {"∅", "∅", "∅"}, - {"∅", "⊤", "∅"}, + {"∅", "𝓤", "∅"}, {"∅", "int", "∅"}, - {"⊤", "~int", "~int"}, + {"𝓤", "~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 ∪ ⊤", "~string ∪ int", "int ∪ ~string"}, + {"~int ∪ string ∪ 𝓤", "~string ∪ int", "int ∪ ~string"}, } { xl := maketl(test.xl) yl := maketl(test.yl) @@ -178,10 +178,10 @@ func TestTermlistEqual(t *testing.T) { want bool }{ {"∅", "∅", true}, - {"∅", "⊤", false}, - {"⊤", "⊤", true}, - {"⊤ ∪ int", "⊤", true}, - {"⊤ ∪ int", "string ∪ ⊤", true}, + {"∅", "𝓤", false}, + {"𝓤", "𝓤", true}, + {"𝓤 ∪ int", "𝓤", true}, + {"𝓤 ∪ int", "string ∪ 𝓤", true}, {"int ∪ ~string", "string ∪ int", false}, {"int ∪ ~string ∪ ∅", "string ∪ int ∪ ~string", true}, } { @@ -200,14 +200,14 @@ func TestTermlistIncludes(t *testing.T) { want bool }{ {"∅", "int", false}, - {"⊤", "int", true}, + {"𝓤", "int", true}, {"~int", "int", true}, {"int", "string", false}, {"~int", "string", false}, {"int ∪ string", "string", true}, {"~int ∪ string", "int", true}, {"~int ∪ string ∪ ∅", "string", true}, - {"~string ∪ ∅ ∪ ⊤", "int", true}, + {"~string ∪ ∅ ∪ 𝓤", "int", true}, } { xl := maketl(test.xl) yl := testTerm(test.typ).typ @@ -224,12 +224,12 @@ func TestTermlistSupersetOf(t *testing.T) { want bool }{ {"∅", "∅", true}, - {"∅", "⊤", false}, + {"∅", "𝓤", false}, {"∅", "int", false}, - {"⊤", "∅", true}, - {"⊤", "⊤", true}, - {"⊤", "int", true}, - {"⊤", "~int", true}, + {"𝓤", "∅", true}, + {"𝓤", "𝓤", true}, + {"𝓤", "int", true}, + {"𝓤", "~int", true}, {"~int", "int", true}, {"~int", "~int", true}, {"int", "~int", false}, @@ -239,7 +239,7 @@ func TestTermlistSupersetOf(t *testing.T) { {"int ∪ string", "~string", false}, {"~int ∪ string", "int", true}, {"~int ∪ string ∪ ∅", "string", true}, - {"~string ∪ ∅ ∪ ⊤", "int", true}, + {"~string ∪ ∅ ∪ 𝓤", "int", true}, } { xl := maketl(test.xl) y := testTerm(test.typ) @@ -256,16 +256,16 @@ func TestTermlistSubsetOf(t *testing.T) { want bool }{ {"∅", "∅", true}, - {"∅", "⊤", true}, - {"⊤", "∅", false}, - {"⊤", "⊤", true}, + {"∅", "𝓤", true}, + {"𝓤", "∅", false}, + {"𝓤", "𝓤", 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 ∪ ⊤", true}, + {"int ∪ ~string", "string ∪ int ∪ 𝓤", true}, {"int ∪ ~string", "string ∪ int ∪ ∅ ∪ string", false}, } { xl := maketl(test.xl) diff --git a/src/cmd/compile/internal/types2/typeset.go b/src/cmd/compile/internal/types2/typeset.go index c5fcb97ff9..83df51389b 100644 --- a/src/cmd/compile/internal/types2/typeset.go +++ b/src/cmd/compile/internal/types2/typeset.go @@ -25,17 +25,19 @@ type TypeSet struct { // 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 { @@ -67,8 +69,8 @@ func (s *TypeSet) String() string { switch { case s.IsEmpty(): return "∅" - case s.IsTop(): - return "⊤" + case s.IsAll(): + return "𝓤" } hasMethods := len(s.methods) > 0 @@ -103,7 +105,7 @@ func (s *TypeSet) String() string { // ---------------------------------------------------------------------------- // 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) } @@ -156,7 +158,7 @@ func (s *TypeSet) underIs(f func(Type) bool) bool { } // 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 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 // 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 @@ -256,7 +258,7 @@ func computeInterfaceTypeSet(check *Checker, pos syntax.Pos, ityp *Interface) *T } // 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 diff --git a/src/cmd/compile/internal/types2/typeterm.go b/src/cmd/compile/internal/types2/typeterm.go index 59a89cb004..8edbefa579 100644 --- a/src/cmd/compile/internal/types2/typeterm.go +++ b/src/cmd/compile/internal/types2/typeterm.go @@ -4,13 +4,10 @@ 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: // // ∅: (*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 // @@ -24,7 +21,7 @@ func (x *term) String() string { case x == nil: return "∅" case x.typ == nil: - return "⊤" + return "𝓤" case x.tilde: return "~" + x.typ.String() default: @@ -41,7 +38,7 @@ func (x *term) equal(y *term) bool { case x.typ == nil || y.typ == nil: return x.typ == y.typ } - // ∅ ⊂ x, y ⊂ ⊤ + // ∅ ⊂ x, y ⊂ 𝓤 return x.tilde == y.tilde && Identical(x.typ, y.typ) } @@ -57,11 +54,11 @@ func (x *term) union(y *term) (_, _ *term) { case y == nil: return x, nil // x ∪ ∅ == x case x.typ == nil: - return x, nil // ⊤ ∪ y == ⊤ + return x, nil // 𝓤 ∪ y == 𝓤 case y.typ == nil: - return y, nil // x ∪ ⊤ == ⊤ + return y, nil // x ∪ 𝓤 == 𝓤 } - // ∅ ⊂ x, y ⊂ ⊤ + // ∅ ⊂ x, y ⊂ 𝓤 if x.disjoint(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: return nil // ∅ ∩ y == ∅ and ∩ ∅ == ∅ case x.typ == nil: - return y // ⊤ ∩ y == y + return y // 𝓤 ∩ y == y case y.typ == nil: - return x // x ∩ ⊤ == x + return x // x ∩ 𝓤 == x } - // ∅ ⊂ x, y ⊂ ⊤ + // ∅ ⊂ x, y ⊂ 𝓤 if x.disjoint(y) { return nil // x ∩ y == ∅ if x ∩ y == ∅ @@ -113,9 +110,9 @@ func (x *term) includes(t Type) bool { case x == nil: return false // t ∈ ∅ == false case x.typ == nil: - return true // t ∈ ⊤ == true + return true // t ∈ 𝓤 == true } - // ∅ ⊂ x ⊂ ⊤ + // ∅ ⊂ x ⊂ 𝓤 u := t if x.tilde { @@ -133,11 +130,11 @@ func (x *term) subsetOf(y *term) bool { case y == nil: return false // x ⊆ ∅ == false since x != ∅ case y.typ == nil: - return true // x ⊆ ⊤ == true + return true // x ⊆ 𝓤 == true case x.typ == nil: - return false // ⊤ ⊆ y == false since y != ⊤ + return false // 𝓤 ⊆ y == false since y != 𝓤 } - // ∅ ⊂ x, y ⊂ ⊤ + // ∅ ⊂ x, y ⊂ 𝓤 if x.disjoint(y) { return false // x ⊆ y == false if x ∩ y == ∅ diff --git a/src/cmd/compile/internal/types2/typeterm_test.go b/src/cmd/compile/internal/types2/typeterm_test.go index cc4e30d989..a8cc362f56 100644 --- a/src/cmd/compile/internal/types2/typeterm_test.go +++ b/src/cmd/compile/internal/types2/typeterm_test.go @@ -11,7 +11,7 @@ import ( var testTerms = map[string]*term{ "∅": nil, - "⊤": {}, + "𝓤": {}, "int": {false, Typ[Int]}, "~int": {true, Typ[Int]}, "string": {false, Typ[String]}, @@ -46,14 +46,14 @@ func testTerm(name string) *term { func TestTermEqual(t *testing.T) { for _, test := range []string{ "∅ ∅ T", - "⊤ ⊤ T", + "𝓤 𝓤 T", "int int T", "~int ~int T", - "∅ ⊤ F", + "∅ 𝓤 F", "∅ int F", "∅ ~int F", - "⊤ int F", - "⊤ ~int F", + "𝓤 int F", + "𝓤 ~int F", "int ~int F", } { args := split(test, 3) @@ -74,12 +74,12 @@ func TestTermEqual(t *testing.T) { func TestTermUnion(t *testing.T) { for _, test := range []string{ "∅ ∅ ∅ ∅", - "∅ ⊤ ⊤ ∅", + "∅ 𝓤 𝓤 ∅", "∅ int int ∅", "∅ ~int ~int ∅", - "⊤ ⊤ ⊤ ∅", - "⊤ int ⊤ ∅", - "⊤ ~int ⊤ ∅", + "𝓤 𝓤 𝓤 ∅", + "𝓤 int 𝓤 ∅", + "𝓤 ~int 𝓤 ∅", "int int int ∅", "int ~int ~int ∅", "int string int string", @@ -87,11 +87,11 @@ func TestTermUnion(t *testing.T) { "~int ~string ~int ~string", // union is symmetric, but the result order isn't - repeat symmetric cases explictly - "⊤ ∅ ⊤ ∅", + "𝓤 ∅ 𝓤 ∅", "int ∅ int ∅", "~int ∅ ~int ∅", - "int ⊤ ⊤ ∅", - "~int ⊤ ⊤ ∅", + "int 𝓤 𝓤 ∅", + "~int 𝓤 𝓤 ∅", "~int int ~int ∅", "string int string int", "~string int ~string int", @@ -111,12 +111,12 @@ func TestTermUnion(t *testing.T) { func TestTermIntersection(t *testing.T) { for _, test := range []string{ "∅ ∅ ∅", - "∅ ⊤ ∅", + "∅ 𝓤 ∅", "∅ int ∅", "∅ ~int ∅", - "⊤ ⊤ ⊤", - "⊤ int int", - "⊤ ~int ~int", + "𝓤 𝓤 𝓤", + "𝓤 int int", + "𝓤 ~int ~int", "int int int", "int ~int int", "int string ∅", @@ -141,7 +141,7 @@ func TestTermIntersection(t *testing.T) { func TestTermIncludes(t *testing.T) { for _, test := range []string{ "∅ int F", - "⊤ int T", + "𝓤 int T", "int int T", "~int int T", "string int F", @@ -160,14 +160,14 @@ func TestTermIncludes(t *testing.T) { func TestTermSubsetOf(t *testing.T) { for _, test := range []string{ "∅ ∅ T", - "⊤ ⊤ T", + "𝓤 𝓤 T", "int int T", "~int ~int T", - "∅ ⊤ T", + "∅ 𝓤 T", "∅ int T", "∅ ~int T", - "⊤ int F", - "⊤ ~int F", + "𝓤 int F", + "𝓤 ~int F", "int ~int T", } { args := split(test, 3) diff --git a/src/cmd/compile/internal/types2/universe.go b/src/cmd/compile/internal/types2/universe.go index 55bf0982b3..f14c079222 100644 --- a/src/cmd/compile/internal/types2/universe.go +++ b/src/cmd/compile/internal/types2/universe.go @@ -99,7 +99,7 @@ func defPredeclaredTypes() { { obj := NewTypeName(nopos, nil, "comparable", nil) 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) def(obj) } -- 2.50.0