1
2
3
4
5 package noder
6
7 import (
8 "fmt"
9 "internal/buildcfg"
10 "internal/types/errors"
11 "regexp"
12 "sort"
13
14 "cmd/compile/internal/base"
15 "cmd/compile/internal/rangefunc"
16 "cmd/compile/internal/syntax"
17 "cmd/compile/internal/types2"
18 "cmd/internal/src"
19 )
20
21 var versionErrorRx = regexp.MustCompile(`requires go[0-9]+\.[0-9]+ or later`)
22
23
24
25
26 func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info, map[*syntax.FuncLit]bool) {
27 if base.SyntaxErrors() != 0 {
28 base.ErrorExit()
29 }
30
31
32 files := make([]*syntax.File, len(noders))
33
34
35 fileBaseMap := make(map[*syntax.PosBase]*syntax.File)
36 for i, p := range noders {
37 files[i] = p.file
38
39
40
41
42
43
44 fileBaseMap[p.file.Pos().FileBase()] = p.file
45 }
46
47
48 ctxt := types2.NewContext()
49 importer := gcimports{
50 ctxt: ctxt,
51 packages: make(map[string]*types2.Package),
52 }
53 conf := types2.Config{
54 Context: ctxt,
55 GoVersion: base.Flag.Lang,
56 IgnoreBranchErrors: true,
57 Importer: &importer,
58 Sizes: types2.SizesFor("gc", buildcfg.GOARCH),
59 EnableAlias: true,
60 }
61 if base.Flag.ErrorURL {
62 conf.ErrorURL = " [go.dev/e/%s]"
63 }
64 info := &types2.Info{
65 StoreTypesInSyntax: true,
66 Defs: make(map[*syntax.Name]types2.Object),
67 Uses: make(map[*syntax.Name]types2.Object),
68 Selections: make(map[*syntax.SelectorExpr]*types2.Selection),
69 Implicits: make(map[syntax.Node]types2.Object),
70 Scopes: make(map[syntax.Node]*types2.Scope),
71 Instances: make(map[*syntax.Name]types2.Instance),
72 FileVersions: make(map[*syntax.PosBase]string),
73
74 }
75 conf.Error = func(err error) {
76 terr := err.(types2.Error)
77 msg := terr.Msg
78 if versionErrorRx.MatchString(msg) {
79 fileBase := terr.Pos.FileBase()
80 fileVersion := info.FileVersions[fileBase]
81 file := fileBaseMap[fileBase]
82 if file == nil {
83
84 } else if file.GoVersion == fileVersion {
85
86 msg = fmt.Sprintf("%s (file declares //go:build %s)", msg, fileVersion)
87 } else {
88
89 msg = fmt.Sprintf("%s (-lang was set to %s; check go.mod)", msg, base.Flag.Lang)
90 }
91 }
92 base.ErrorfAt(m.makeXPos(terr.Pos), terr.Code, "%s", msg)
93 }
94
95 pkg, err := conf.Check(base.Ctxt.Pkgpath, files, info)
96 base.ExitIfErrors()
97 if err != nil {
98 base.FatalfAt(src.NoXPos, "conf.Check error: %v", err)
99 }
100
101
102
103 var f cycleFinder
104 for _, file := range files {
105 syntax.Inspect(file, func(n syntax.Node) bool {
106 if n, ok := n.(*syntax.InterfaceType); ok {
107 if f.hasCycle(types2.Unalias(n.GetTypeInfo().Type).(*types2.Interface)) {
108 base.ErrorfAt(m.makeXPos(n.Pos()), errors.InvalidTypeCycle, "invalid recursive type: anonymous interface refers to itself (see https://go.dev/issue/56103)")
109
110 for typ := range f.cyclic {
111 f.cyclic[typ] = false
112 }
113 }
114 return false
115 }
116 return true
117 })
118 }
119 base.ExitIfErrors()
120
121
122
123 {
124 type nihTarg struct {
125 pos src.XPos
126 typ types2.Type
127 }
128 var nihTargs []nihTarg
129
130 for name, inst := range info.Instances {
131 for i := 0; i < inst.TypeArgs.Len(); i++ {
132 if targ := inst.TypeArgs.At(i); isNotInHeap(targ) {
133 nihTargs = append(nihTargs, nihTarg{m.makeXPos(name.Pos()), targ})
134 }
135 }
136 }
137 sort.Slice(nihTargs, func(i, j int) bool {
138 ti, tj := nihTargs[i], nihTargs[j]
139 return ti.pos.Before(tj.pos)
140 })
141 for _, targ := range nihTargs {
142 base.ErrorfAt(targ.pos, 0, "cannot use incomplete (or unallocatable) type as a type argument: %v", targ.typ)
143 }
144 }
145 base.ExitIfErrors()
146
147
148
149 {
150 for _, file := range files {
151 syntax.Inspect(file, func(n syntax.Node) bool {
152 if n, ok := n.(*syntax.TypeDecl); ok {
153 switch n := n.Type.(type) {
154 case *syntax.MapType:
155 typ := n.GetTypeInfo().Type.Underlying().(*types2.Map)
156 if isNotInHeap(typ.Key()) {
157 base.ErrorfAt(m.makeXPos(n.Pos()), 0, "incomplete (or unallocatable) map key not allowed")
158 }
159 if isNotInHeap(typ.Elem()) {
160 base.ErrorfAt(m.makeXPos(n.Pos()), 0, "incomplete (or unallocatable) map value not allowed")
161 }
162 case *syntax.ChanType:
163 typ := n.GetTypeInfo().Type.Underlying().(*types2.Chan)
164 if isNotInHeap(typ.Elem()) {
165 base.ErrorfAt(m.makeXPos(n.Pos()), 0, "chan of incomplete (or unallocatable) type not allowed")
166 }
167 }
168 }
169 return true
170 })
171 }
172 }
173 base.ExitIfErrors()
174
175
176
177
178
179
180
181
182 rangeInfo := rangefunc.Rewrite(pkg, info, files)
183
184 return pkg, info, rangeInfo
185 }
186
187
188 type cycleFinder struct {
189 cyclic map[*types2.Interface]bool
190 }
191
192
193 func (f *cycleFinder) hasCycle(typ *types2.Interface) bool {
194
195
196
197
198 for i := 0; i < typ.NumMethods(); i++ {
199 if f.visit(typ.Method(i).Type()) {
200 return true
201 }
202 }
203 return false
204 }
205
206
207 func (f *cycleFinder) visit(typ0 types2.Type) bool {
208 for {
209 switch typ := types2.Unalias(typ0).(type) {
210 default:
211 base.Fatalf("unexpected type: %T", typ)
212
213 case *types2.Basic, *types2.Named, *types2.TypeParam:
214 return false
215 case *types2.Pointer:
216 typ0 = typ.Elem()
217 case *types2.Array:
218 typ0 = typ.Elem()
219 case *types2.Chan:
220 typ0 = typ.Elem()
221 case *types2.Map:
222 if f.visit(typ.Key()) {
223 return true
224 }
225 typ0 = typ.Elem()
226 case *types2.Slice:
227 typ0 = typ.Elem()
228
229 case *types2.Struct:
230 for i := 0; i < typ.NumFields(); i++ {
231 if f.visit(typ.Field(i).Type()) {
232 return true
233 }
234 }
235 return false
236
237 case *types2.Interface:
238
239 if typ.NumExplicitMethods() == 0 && typ.NumEmbeddeds() == 0 {
240 return false
241 }
242
243
244
245
246
247
248
249 if x, ok := f.cyclic[typ]; ok {
250 return x
251 }
252 if f.cyclic == nil {
253 f.cyclic = make(map[*types2.Interface]bool)
254 }
255 f.cyclic[typ] = true
256 if f.hasCycle(typ) {
257 return true
258 }
259 f.cyclic[typ] = false
260 return false
261
262 case *types2.Signature:
263 return f.visit(typ.Params()) || f.visit(typ.Results())
264 case *types2.Tuple:
265 for i := 0; i < typ.Len(); i++ {
266 if f.visit(typ.At(i).Type()) {
267 return true
268 }
269 }
270 return false
271 }
272 }
273 }
274
View as plain text