]> Cypherpunks repositories - gostls13.git/commitdiff
go/types, types2: clarify Named, Alias, TypeName, Object
authorAlan Donovan <adonovan@google.com>
Fri, 9 Aug 2024 19:00:35 +0000 (15:00 -0400)
committerAlan Donovan <adonovan@google.com>
Fri, 20 Sep 2024 13:54:44 +0000 (13:54 +0000)
Updates #65855
Updates #66890

Change-Id: I167c9de818049cae02f0d99f8e0fb4017e07bea9
Reviewed-on: https://go-review.googlesource.com/c/go/+/604476
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
src/cmd/compile/internal/types2/alias.go
src/cmd/compile/internal/types2/named.go
src/cmd/compile/internal/types2/object.go
src/cmd/compile/internal/types2/typeparam.go
src/go/types/alias.go
src/go/types/named.go
src/go/types/object.go
src/go/types/typeparam.go

index 07f35b1854acafdad8d7fd1ea4763be23fe21928..6a6b96a6e3277475263f4693d3ea3e0f3ac2134d 100644 (file)
@@ -10,11 +10,36 @@ import (
 )
 
 // An Alias represents an alias type.
-// Whether or not Alias types are created is controlled by the
-// gotypesalias setting with the GODEBUG environment variable.
-// For gotypesalias=1, alias declarations produce an Alias type.
-// Otherwise, the alias information is only in the type name,
-// which points directly to the actual (aliased) type.
+//
+// Alias types are created by alias declarations such as:
+//
+//     type A = int
+//
+// The type on the right-hand side of the declaration can be accessed
+// using [Alias.Rhs]. This type may itself be an alias.
+// Call [Unalias] to obtain the first non-alias type in a chain of
+// alias type declarations.
+//
+// Like a defined ([Named]) type, an alias type has a name.
+// Use the [Alias.Obj] method to access its [TypeName] object.
+//
+// Historically, Alias types were not materialized so that, in the example
+// above, A's type was represented by a Basic (int), not an Alias
+// whose [Alias.Rhs] is int. But Go 1.24 allows you to declare an
+// alias type with type parameters or arguments:
+//
+//     type Set[K comparable] = map[K]bool
+//     s := make(Set[String])
+//
+// and this requires that Alias types be materialized. Use the
+// [Alias.TypeParams] and [Alias.TypeArgs] methods to access them.
+//
+// To ease the transition, the Alias type was introduced in go1.22,
+// but the type-checker would not construct values of this type unless
+// the GODEBUG=gotypesalias=1 environment variable was provided.
+// Starting in go1.23, this variable is enabled by default.
+// This setting also causes the predeclared type "any" to be
+// represented as an Alias, not a bare [Interface].
 type Alias struct {
        obj     *TypeName      // corresponding declared alias object
        orig    *Alias         // original, uninstantiated alias
index 92dedf51d568a63d009b3293b66b152bfb69ef31..a9a27c93206c3685c21a8a8a2bd293e9329718c8 100644 (file)
@@ -92,6 +92,17 @@ import (
 // in its "lineage".
 
 // A Named represents a named (defined) type.
+//
+// A declaration such as:
+//
+//     type S struct { ... }
+//
+// creates a defined type whose underlying type is a struct,
+// and binds this type to the object S, a [TypeName].
+// Use [Named.Underlying] to access the underlying type.
+// Use [Named.Obj] to obtain the object S.
+//
+// Before type aliases (Go 1.9), the spec called defined types "named types".
 type Named struct {
        check *Checker  // non-nil during type-checking; nil otherwise
        obj   *TypeName // corresponding declared object for declared types; see above for instantiated types
index f9a25473a15cd7e4d26146edfd438aca0044435e..d29c9a3df6766552f0ebb762e07338d1d99f2d6d 100644 (file)
@@ -14,9 +14,15 @@ import (
        "unicode/utf8"
 )
 
-// An Object describes a named language entity such as a package,
-// constant, type, variable, function (incl. methods), or label.
-// All objects implement the Object interface.
+// An Object is a named language entity.
+// An Object may be a constant ([Const]), type name ([TypeName]),
+// variable or struct field ([Var]), function or method ([Func]),
+// imported package ([PkgName]), label ([Label]),
+// built-in function ([Builtin]),
+// or the predeclared identifier 'nil' ([Nil]).
+//
+// The environment, which is structured as a tree of Scopes,
+// maps each name to the unique Object that it denotes.
 type Object interface {
        Parent() *Scope  // scope in which this object is declared; nil for methods and struct fields
        Pos() syntax.Pos // position of object identifier in declaration
@@ -27,6 +33,7 @@ type Object interface {
        Id() string      // object name if exported, qualified name if not exported (see func Id)
 
        // String returns a human-readable string of the object.
+       // Use [ObjectString] to control how package names are formatted in the string.
        String() string
 
        // order reflects a package-level object's source order: if object
@@ -257,7 +264,11 @@ func (obj *Const) Val() constant.Value { return obj.val }
 
 func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression
 
-// A TypeName represents a name for a (defined or alias) type.
+// A TypeName is an [Object] that represents a type with a name:
+// a defined type ([Named]),
+// an alias type ([Alias]),
+// a type parameter ([TypeParam]),
+// or a predeclared type such as int or error.
 type TypeName struct {
        object
 }
index e22981e1ad0c00d958240c80acc13bcd91323e94..c812df16ea003f54ea03d064fb96e5a1b1050e81 100644 (file)
@@ -15,7 +15,10 @@ var lastID atomic.Uint32
 // each call, starting with 1. It may be called concurrently.
 func nextID() uint64 { return uint64(lastID.Add(1)) }
 
-// A TypeParam represents a type parameter type.
+// A TypeParam represents the type of a type parameter in a generic declaration.
+//
+// A TypeParam has a name; use the [TypeParam.Obj] method to access
+// its [TypeName] object.
 type TypeParam struct {
        check *Checker  // for lazy type bound completion
        id    uint64    // unique id, for debugging only
index 7adb3deb58bbc75d352d120db4bc7c3bc43a2d4a..3836ce9bb96420387283b27cf79f1558be85fb35 100644 (file)
@@ -13,11 +13,36 @@ import (
 )
 
 // An Alias represents an alias type.
-// Whether or not Alias types are created is controlled by the
-// gotypesalias setting with the GODEBUG environment variable.
-// For gotypesalias=1, alias declarations produce an Alias type.
-// Otherwise, the alias information is only in the type name,
-// which points directly to the actual (aliased) type.
+//
+// Alias types are created by alias declarations such as:
+//
+//     type A = int
+//
+// The type on the right-hand side of the declaration can be accessed
+// using [Alias.Rhs]. This type may itself be an alias.
+// Call [Unalias] to obtain the first non-alias type in a chain of
+// alias type declarations.
+//
+// Like a defined ([Named]) type, an alias type has a name.
+// Use the [Alias.Obj] method to access its [TypeName] object.
+//
+// Historically, Alias types were not materialized so that, in the example
+// above, A's type was represented by a Basic (int), not an Alias
+// whose [Alias.Rhs] is int. But Go 1.24 allows you to declare an
+// alias type with type parameters or arguments:
+//
+//     type Set[K comparable] = map[K]bool
+//     s := make(Set[String])
+//
+// and this requires that Alias types be materialized. Use the
+// [Alias.TypeParams] and [Alias.TypeArgs] methods to access them.
+//
+// To ease the transition, the Alias type was introduced in go1.22,
+// but the type-checker would not construct values of this type unless
+// the GODEBUG=gotypesalias=1 environment variable was provided.
+// Starting in go1.23, this variable is enabled by default.
+// This setting also causes the predeclared type "any" to be
+// represented as an Alias, not a bare [Interface].
 type Alias struct {
        obj     *TypeName      // corresponding declared alias object
        orig    *Alias         // original, uninstantiated alias
index 21d0f4f59f838893c63b06bba1b996a37cc5db2f..1282abfa3f078a1889b31c4214ee1fb3f801bfc0 100644 (file)
@@ -95,6 +95,17 @@ import (
 // in its "lineage".
 
 // A Named represents a named (defined) type.
+//
+// A declaration such as:
+//
+//     type S struct { ... }
+//
+// creates a defined type whose underlying type is a struct,
+// and binds this type to the object S, a [TypeName].
+// Use [Named.Underlying] to access the underlying type.
+// Use [Named.Obj] to obtain the object S.
+//
+// Before type aliases (Go 1.9), the spec called defined types "named types".
 type Named struct {
        check *Checker  // non-nil during type-checking; nil otherwise
        obj   *TypeName // corresponding declared object for declared types; see above for instantiated types
index cc014188324a3e25381e0fa3c1baa8365081ad95..06d5fbe5116febeb05412313ec01b6cac05c9650 100644 (file)
@@ -17,9 +17,15 @@ import (
        "unicode/utf8"
 )
 
-// An Object describes a named language entity such as a package,
-// constant, type, variable, function (incl. methods), or label.
-// All objects implement the Object interface.
+// An Object is a named language entity.
+// An Object may be a constant ([Const]), type name ([TypeName]),
+// variable or struct field ([Var]), function or method ([Func]),
+// imported package ([PkgName]), label ([Label]),
+// built-in function ([Builtin]),
+// or the predeclared identifier 'nil' ([Nil]).
+//
+// The environment, which is structured as a tree of Scopes,
+// maps each name to the unique Object that it denotes.
 type Object interface {
        Parent() *Scope // scope in which this object is declared; nil for methods and struct fields
        Pos() token.Pos // position of object identifier in declaration
@@ -30,6 +36,7 @@ type Object interface {
        Id() string     // object name if exported, qualified name if not exported (see func Id)
 
        // String returns a human-readable string of the object.
+       // Use [ObjectString] to control how package names are formatted in the string.
        String() string
 
        // order reflects a package-level object's source order: if object
@@ -260,7 +267,11 @@ func (obj *Const) Val() constant.Value { return obj.val }
 
 func (*Const) isDependency() {} // a constant may be a dependency of an initialization expression
 
-// A TypeName represents a name for a (defined or alias) type.
+// A TypeName is an [Object] that represents a type with a name:
+// a defined type ([Named]),
+// an alias type ([Alias]),
+// a type parameter ([TypeParam]),
+// or a predeclared type such as int or error.
 type TypeName struct {
        object
 }
index 789b63d7a15aaebd127c60a41553f057fcca55bc..42284307e2debc23b61f245e06f236e378c088f8 100644 (file)
@@ -18,7 +18,10 @@ var lastID atomic.Uint32
 // each call, starting with 1. It may be called concurrently.
 func nextID() uint64 { return uint64(lastID.Add(1)) }
 
-// A TypeParam represents a type parameter type.
+// A TypeParam represents the type of a type parameter in a generic declaration.
+//
+// A TypeParam has a name; use the [TypeParam.Obj] method to access
+// its [TypeName] object.
 type TypeParam struct {
        check *Checker  // for lazy type bound completion
        id    uint64    // unique id, for debugging only