File tree 4 files changed +64
-13
lines changed
4 files changed +64
-13
lines changed Original file line number Diff line number Diff line change @@ -715,12 +715,10 @@ func (subst *subster) typ(t *types.Type) *types.Type {
715
715
return newsym .Def .Type ()
716
716
}
717
717
718
- // In order to deal with recursive generic types, create a TFORW type
719
- // initially and set its Def field, so it can be found if this type
720
- // appears recursively within the type.
721
- forw = types .New (types .TFORW )
722
- forw .SetSym (newsym )
723
- newsym .Def = ir .TypeNode (forw )
718
+ // In order to deal with recursive generic types, create a TFORW
719
+ // type initially and set the Def field of its sym, so it can be
720
+ // found if this type appears recursively within the type.
721
+ forw = newNamedTypeWithSym (t .Pos (), newsym )
724
722
//println("Creating new type by sub", newsym.Name, forw.HasTParam())
725
723
forw .SetRParams (neededTargs )
726
724
}
@@ -894,3 +892,13 @@ func deref(t *types.Type) *types.Type {
894
892
}
895
893
return t
896
894
}
895
+
896
+ // newNamedTypeWithSym returns a TFORW type t with name specified by sym, such
897
+ // that t.nod and sym.Def are set correctly.
898
+ func newNamedTypeWithSym (pos src.XPos , sym * types.Sym ) * types.Type {
899
+ name := ir .NewDeclNameAt (pos , ir .OTYPE , sym )
900
+ forw := types .NewNamed (name )
901
+ name .SetType (forw )
902
+ sym .Def = name
903
+ return forw
904
+ }
Original file line number Diff line number Diff line change @@ -120,10 +120,8 @@ func (g *irgen) typ0(typ types2.Type) *types.Type {
120
120
// which may set HasTParam) before translating the
121
121
// underlying type itself, so we handle recursion
122
122
// correctly, including via method signatures.
123
- ntyp := types . New ( types . TFORW )
123
+ ntyp := newNamedTypeWithSym ( g . pos ( typ . Obj (). Pos ()), s )
124
124
g .typs [typ ] = ntyp
125
- ntyp .SetSym (s )
126
- s .Def = ir .TypeNode (ntyp )
127
125
128
126
// If ntyp still has type params, then we must be
129
127
// referencing something like 'value[T2]', as when
Original file line number Diff line number Diff line change @@ -160,8 +160,9 @@ type Type struct {
160
160
methods Fields
161
161
allMethods Fields
162
162
163
- nod Object // canonical OTYPE node
164
- underlying * Type // original type (type literal or predefined type)
163
+ // canonical OTYPE node for a named type (should be an ir.Name node with same sym)
164
+ nod Object
165
+ underlying * Type // original type (type literal or predefined type)
165
166
166
167
// Cache of composite types, with this type being the element type.
167
168
cache struct {
@@ -1642,15 +1643,15 @@ var (
1642
1643
TypeResultMem = newResults ([]* Type {TypeMem })
1643
1644
)
1644
1645
1645
- // NewNamed returns a new named type for the given type name.
1646
+ // NewNamed returns a new named type for the given type name. obj should be an ir.Name.
1646
1647
func NewNamed (obj Object ) * Type {
1647
1648
t := New (TFORW )
1648
1649
t .sym = obj .Sym ()
1649
1650
t .nod = obj
1650
1651
return t
1651
1652
}
1652
1653
1653
- // Obj returns the type name for the named type t.
1654
+ // Obj returns the canonical type name node for a named type t, nil for an unnamed type .
1654
1655
func (t * Type ) Obj () Object {
1655
1656
if t .sym != nil {
1656
1657
return t .nod
Original file line number Diff line number Diff line change
1
+ // run -gcflags=-G=3
2
+
3
+ // Copyright 2021 The Go Authors. All rights reserved.
4
+ // Use of this source code is governed by a BSD-style
5
+ // license that can be found in the LICENSE file.
6
+
7
+ package main
8
+
9
+ type I interface {}
10
+
11
+ type _S [T any ] struct {
12
+ * T
13
+ }
14
+
15
+ // F is a non-generic function, but has a type _S[I] which is instantiated from a
16
+ // generic type. Test that _S[I] is successfully exported.
17
+ func F () {
18
+ v := _S [I ]{}
19
+ if v .T != nil {
20
+ panic (v )
21
+ }
22
+ }
23
+
24
+ // Testing the various combinations of method expressions.
25
+ type S1 struct {}
26
+ func (* S1 ) M () {}
27
+
28
+ type S2 struct {}
29
+ func (S2 ) M () {}
30
+
31
+ func _F1 [T interface { M () }](t T ) {
32
+ _ = T .M
33
+ }
34
+
35
+ func F2 () {
36
+ _F1 (& S1 {})
37
+ _F1 (S2 {})
38
+ _F1 (& S2 {})
39
+ }
40
+
41
+ func main () {
42
+ F ()
43
+ F2 ()
44
+ }
You can’t perform that action at this time.
0 commit comments