]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/types2/alias.go
go/types, types2: introduce _Alias type node
[gostls13.git] / src / cmd / compile / internal / types2 / alias.go
1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package types2
6
7 import "fmt"
8
9 // Names starting with a _ are intended to be exported eventually
10 // (go.dev/issue/63223).
11
12 // An _Alias represents an alias type.
13 type _Alias struct {
14         obj     *TypeName // corresponding declared alias object
15         fromRHS Type      // RHS of type alias declaration; may be an alias
16         actual  Type      // actual (aliased) type; never an alias
17 }
18
19 // _NewAlias creates a new Alias type with the given type name and rhs.
20 // rhs must not be nil.
21 func _NewAlias(obj *TypeName, rhs Type) *_Alias {
22         return (*Checker)(nil).newAlias(obj, rhs)
23 }
24
25 func (a *_Alias) Underlying() Type { return a.actual.Underlying() }
26 func (a *_Alias) String() string   { return TypeString(a, nil) }
27
28 // Type accessors
29
30 // _Unalias returns t if it is not an alias type;
31 // otherwise it follows t's alias chain until it
32 // reaches a non-alias type which is then returned.
33 // Consequently, the result is never an alias type.
34 func _Unalias(t Type) Type {
35         if a0, _ := t.(*_Alias); a0 != nil {
36                 if a0.actual != nil {
37                         return a0.actual
38                 }
39                 for a := a0; ; {
40                         t = a.fromRHS
41                         a, _ = t.(*_Alias)
42                         if a == nil {
43                                 break
44                         }
45                 }
46                 if t == nil {
47                         panic(fmt.Sprintf("non-terminated alias %s", a0.obj.name))
48                 }
49                 a0.actual = t
50         }
51         return t
52 }
53
54 // asNamed returns t as *Named if that is t's
55 // actual type. It returns nil otherwise.
56 func asNamed(t Type) *Named {
57         n, _ := _Unalias(t).(*Named)
58         return n
59 }
60
61 // newAlias creates a new Alias type with the given type name and rhs.
62 // rhs must not be nil.
63 func (check *Checker) newAlias(obj *TypeName, rhs Type) *_Alias {
64         assert(rhs != nil)
65         a := &_Alias{obj, rhs, nil}
66         if obj.typ == nil {
67                 obj.typ = a
68         }
69
70         // Ensure that a.actual is set at the end of type checking.
71         if check != nil {
72                 check.needsCleanup(a)
73         }
74
75         return a
76 }
77
78 func (a *_Alias) cleanup() {
79         _Unalias(a)
80 }