Source file src/go/types/builtins.go
1
2
3
4
5
6
7 package types
8
9 import (
10 "go/ast"
11 "go/constant"
12 "go/token"
13 )
14
15
16
17
18
19
20 func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ bool) {
21
22 bin := predeclaredFuncs[id]
23 if call.Ellipsis.IsValid() && id != _Append {
24 check.invalidOp(call.Ellipsis, "invalid use of ... with built-in %s", bin.name)
25 check.use(call.Args...)
26 return
27 }
28
29
30
31
32
33
34 if id == _Len || id == _Cap {
35 defer func(b bool) {
36 check.hasCallOrRecv = b
37 }(check.hasCallOrRecv)
38 check.hasCallOrRecv = false
39 }
40
41
42 var arg getter
43 nargs := len(call.Args)
44 switch id {
45 default:
46
47 arg, nargs, _ = unpack(func(x *operand, i int) { check.multiExpr(x, call.Args[i]) }, nargs, false)
48 if arg == nil {
49 return
50 }
51
52 if nargs > 0 {
53 arg(x, 0)
54 if x.mode == invalid {
55 return
56 }
57 }
58 case _Make, _New, _Offsetof, _Trace:
59
60 }
61
62
63 {
64 msg := ""
65 if nargs < bin.nargs {
66 msg = "not enough"
67 } else if !bin.variadic && nargs > bin.nargs {
68 msg = "too many"
69 }
70 if msg != "" {
71 check.invalidOp(call.Rparen, "%s arguments for %s (expected %d, found %d)", msg, call, bin.nargs, nargs)
72 return
73 }
74 }
75
76 switch id {
77 case _Append:
78
79
80
81
82
83 S := x.typ
84 var T Type
85 if s, _ := S.Underlying().(*Slice); s != nil {
86 T = s.elem
87 } else {
88 check.invalidArg(x.pos(), "%s is not a slice", x)
89 return
90 }
91
92
93 alist := []operand{*x}
94
95
96
97
98 if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check, NewSlice(universeByte), nil) {
99 arg(x, 1)
100 if x.mode == invalid {
101 return
102 }
103 if isString(x.typ) {
104 if check.Types != nil {
105 sig := makeSig(S, S, x.typ)
106 sig.variadic = true
107 check.recordBuiltinType(call.Fun, sig)
108 }
109 x.mode = value
110 x.typ = S
111 break
112 }
113 alist = append(alist, *x)
114
115 }
116
117
118 sig := makeSig(S, S, NewSlice(T))
119 sig.variadic = true
120 check.arguments(x, call, sig, func(x *operand, i int) {
121
122 if i < len(alist) {
123 *x = alist[i]
124 return
125 }
126 arg(x, i)
127 }, nargs)
128
129
130 x.mode = value
131 x.typ = S
132 if check.Types != nil {
133 check.recordBuiltinType(call.Fun, sig)
134 }
135
136 case _Cap, _Len:
137
138
139 mode := invalid
140 var typ Type
141 var val constant.Value
142 switch typ = implicitArrayDeref(x.typ.Underlying()); t := typ.(type) {
143 case *Basic:
144 if isString(t) && id == _Len {
145 if x.mode == constant_ {
146 mode = constant_
147 val = constant.MakeInt64(int64(len(constant.StringVal(x.val))))
148 } else {
149 mode = value
150 }
151 }
152
153 case *Array:
154 mode = value
155
156
157
158
159 if !check.hasCallOrRecv {
160 mode = constant_
161 if t.len >= 0 {
162 val = constant.MakeInt64(t.len)
163 } else {
164 val = constant.MakeUnknown()
165 }
166 }
167
168 case *Slice, *Chan:
169 mode = value
170
171 case *Map:
172 if id == _Len {
173 mode = value
174 }
175 }
176
177 if mode == invalid && typ != Typ[Invalid] {
178 check.invalidArg(x.pos(), "%s for %s", x, bin.name)
179 return
180 }
181
182 x.mode = mode
183 x.typ = Typ[Int]
184 x.val = val
185 if check.Types != nil && mode != constant_ {
186 check.recordBuiltinType(call.Fun, makeSig(x.typ, typ))
187 }
188
189 case _Close:
190
191 c, _ := x.typ.Underlying().(*Chan)
192 if c == nil {
193 check.invalidArg(x.pos(), "%s is not a channel", x)
194 return
195 }
196 if c.dir == RecvOnly {
197 check.invalidArg(x.pos(), "%s must not be a receive-only channel", x)
198 return
199 }
200
201 x.mode = novalue
202 if check.Types != nil {
203 check.recordBuiltinType(call.Fun, makeSig(nil, c))
204 }
205
206 case _Complex:
207
208 var y operand
209 arg(&y, 1)
210 if y.mode == invalid {
211 return
212 }
213
214
215 d := 0
216 if isUntyped(x.typ) {
217 d |= 1
218 }
219 if isUntyped(y.typ) {
220 d |= 2
221 }
222 switch d {
223 case 0:
224
225 case 1:
226
227 check.convertUntyped(x, y.typ)
228 case 2:
229
230 check.convertUntyped(&y, x.typ)
231 case 3:
232
233
234
235
236
237
238
239
240 if x.mode == constant_ && y.mode == constant_ {
241 toFloat := func(x *operand) {
242 if isNumeric(x.typ) && constant.Sign(constant.Imag(x.val)) == 0 {
243 x.typ = Typ[UntypedFloat]
244 }
245 }
246 toFloat(x)
247 toFloat(&y)
248 } else {
249 check.convertUntyped(x, Typ[Float64])
250 check.convertUntyped(&y, Typ[Float64])
251
252
253 }
254 }
255 if x.mode == invalid || y.mode == invalid {
256 return
257 }
258
259
260 if !Identical(x.typ, y.typ) {
261 check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
262 return
263 }
264
265
266 if !isFloat(x.typ) {
267 check.invalidArg(x.pos(), "arguments have type %s, expected floating-point", x.typ)
268 return
269 }
270
271
272 if x.mode == constant_ && y.mode == constant_ {
273 x.val = constant.BinaryOp(constant.ToFloat(x.val), token.ADD, constant.MakeImag(constant.ToFloat(y.val)))
274 } else {
275 x.mode = value
276 }
277
278
279 var res BasicKind
280 switch x.typ.Underlying().(*Basic).kind {
281 case Float32:
282 res = Complex64
283 case Float64:
284 res = Complex128
285 case UntypedFloat:
286 res = UntypedComplex
287 default:
288 unreachable()
289 }
290 resTyp := Typ[res]
291
292 if check.Types != nil && x.mode != constant_ {
293 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ, x.typ))
294 }
295
296 x.typ = resTyp
297
298 case _Copy:
299
300 var dst Type
301 if t, _ := x.typ.Underlying().(*Slice); t != nil {
302 dst = t.elem
303 }
304
305 var y operand
306 arg(&y, 1)
307 if y.mode == invalid {
308 return
309 }
310 var src Type
311 switch t := y.typ.Underlying().(type) {
312 case *Basic:
313 if isString(y.typ) {
314 src = universeByte
315 }
316 case *Slice:
317 src = t.elem
318 }
319
320 if dst == nil || src == nil {
321 check.invalidArg(x.pos(), "copy expects slice arguments; found %s and %s", x, &y)
322 return
323 }
324
325 if !Identical(dst, src) {
326 check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
327 return
328 }
329
330 if check.Types != nil {
331 check.recordBuiltinType(call.Fun, makeSig(Typ[Int], x.typ, y.typ))
332 }
333 x.mode = value
334 x.typ = Typ[Int]
335
336 case _Delete:
337
338 m, _ := x.typ.Underlying().(*Map)
339 if m == nil {
340 check.invalidArg(x.pos(), "%s is not a map", x)
341 return
342 }
343 arg(x, 1)
344 if x.mode == invalid {
345 return
346 }
347
348 if !x.assignableTo(check, m.key, nil) {
349 check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
350 return
351 }
352
353 x.mode = novalue
354 if check.Types != nil {
355 check.recordBuiltinType(call.Fun, makeSig(nil, m, m.key))
356 }
357
358 case _Imag, _Real:
359
360
361
362
363 if isUntyped(x.typ) {
364 if x.mode == constant_ {
365
366
367 if isNumeric(x.typ) {
368 x.typ = Typ[UntypedComplex]
369 }
370 } else {
371
372
373
374
375 check.convertUntyped(x, Typ[Complex128])
376
377 if x.mode == invalid {
378 return
379 }
380 }
381 }
382
383
384 if !isComplex(x.typ) {
385 check.invalidArg(x.pos(), "argument has type %s, expected complex type", x.typ)
386 return
387 }
388
389
390 if x.mode == constant_ {
391 if id == _Real {
392 x.val = constant.Real(x.val)
393 } else {
394 x.val = constant.Imag(x.val)
395 }
396 } else {
397 x.mode = value
398 }
399
400
401 var res BasicKind
402 switch x.typ.Underlying().(*Basic).kind {
403 case Complex64:
404 res = Float32
405 case Complex128:
406 res = Float64
407 case UntypedComplex:
408 res = UntypedFloat
409 default:
410 unreachable()
411 }
412 resTyp := Typ[res]
413
414 if check.Types != nil && x.mode != constant_ {
415 check.recordBuiltinType(call.Fun, makeSig(resTyp, x.typ))
416 }
417
418 x.typ = resTyp
419
420 case _Make:
421
422
423
424 arg0 := call.Args[0]
425 T := check.typ(arg0)
426 if T == Typ[Invalid] {
427 return
428 }
429
430 var min int
431 switch T.Underlying().(type) {
432 case *Slice:
433 min = 2
434 case *Map, *Chan:
435 min = 1
436 default:
437 check.invalidArg(arg0.Pos(), "cannot make %s; type must be slice, map, or channel", arg0)
438 return
439 }
440 if nargs < min || min+1 < nargs {
441 check.errorf(call.Pos(), "%v expects %d or %d arguments; found %d", call, min, min+1, nargs)
442 return
443 }
444 var sizes []int64
445 for _, arg := range call.Args[1:] {
446 if s, ok := check.index(arg, -1); ok && s >= 0 {
447 sizes = append(sizes, s)
448 }
449 }
450 if len(sizes) == 2 && sizes[0] > sizes[1] {
451 check.invalidArg(call.Args[1].Pos(), "length and capacity swapped")
452
453 }
454 x.mode = value
455 x.typ = T
456 if check.Types != nil {
457 params := [...]Type{T, Typ[Int], Typ[Int]}
458 check.recordBuiltinType(call.Fun, makeSig(x.typ, params[:1+len(sizes)]...))
459 }
460
461 case _New:
462
463
464 T := check.typ(call.Args[0])
465 if T == Typ[Invalid] {
466 return
467 }
468
469 x.mode = value
470 x.typ = &Pointer{base: T}
471 if check.Types != nil {
472 check.recordBuiltinType(call.Fun, makeSig(x.typ, T))
473 }
474
475 case _Panic:
476
477
478
479 if check.sig != nil && check.sig.results.Len() > 0 {
480
481 p := check.isPanic
482 if p == nil {
483
484 p = make(map[*ast.CallExpr]bool)
485 check.isPanic = p
486 }
487 p[call] = true
488 }
489
490 check.assignment(x, &emptyInterface, "argument to panic")
491 if x.mode == invalid {
492 return
493 }
494
495 x.mode = novalue
496 if check.Types != nil {
497 check.recordBuiltinType(call.Fun, makeSig(nil, &emptyInterface))
498 }
499
500 case _Print, _Println:
501
502
503 var params []Type
504 if nargs > 0 {
505 params = make([]Type, nargs)
506 for i := 0; i < nargs; i++ {
507 if i > 0 {
508 arg(x, i)
509 }
510 check.assignment(x, nil, "argument to "+predeclaredFuncs[id].name)
511 if x.mode == invalid {
512
513 return
514 }
515 params[i] = x.typ
516 }
517 }
518
519 x.mode = novalue
520 if check.Types != nil {
521 check.recordBuiltinType(call.Fun, makeSig(nil, params...))
522 }
523
524 case _Recover:
525
526 x.mode = value
527 x.typ = &emptyInterface
528 if check.Types != nil {
529 check.recordBuiltinType(call.Fun, makeSig(x.typ))
530 }
531
532 case _Alignof:
533
534 check.assignment(x, nil, "argument to unsafe.Alignof")
535 if x.mode == invalid {
536 return
537 }
538
539 x.mode = constant_
540 x.val = constant.MakeInt64(check.conf.alignof(x.typ))
541 x.typ = Typ[Uintptr]
542
543
544 case _Offsetof:
545
546
547 arg0 := call.Args[0]
548 selx, _ := unparen(arg0).(*ast.SelectorExpr)
549 if selx == nil {
550 check.invalidArg(arg0.Pos(), "%s is not a selector expression", arg0)
551 check.use(arg0)
552 return
553 }
554
555 check.expr(x, selx.X)
556 if x.mode == invalid {
557 return
558 }
559
560 base := derefStructPtr(x.typ)
561 sel := selx.Sel.Name
562 obj, index, indirect := LookupFieldOrMethod(base, false, check.pkg, sel)
563 switch obj.(type) {
564 case nil:
565 check.invalidArg(x.pos(), "%s has no single field %s", base, sel)
566 return
567 case *Func:
568
569
570
571
572 check.invalidArg(arg0.Pos(), "%s is a method value", arg0)
573 return
574 }
575 if indirect {
576 check.invalidArg(x.pos(), "field %s is embedded via a pointer in %s", sel, base)
577 return
578 }
579
580
581 check.recordSelection(selx, FieldVal, base, obj, index, false)
582
583 offs := check.conf.offsetof(base, index)
584 x.mode = constant_
585 x.val = constant.MakeInt64(offs)
586 x.typ = Typ[Uintptr]
587
588
589 case _Sizeof:
590
591 check.assignment(x, nil, "argument to unsafe.Sizeof")
592 if x.mode == invalid {
593 return
594 }
595
596 x.mode = constant_
597 x.val = constant.MakeInt64(check.conf.sizeof(x.typ))
598 x.typ = Typ[Uintptr]
599
600
601 case _Assert:
602
603
604
605 if x.mode != constant_ || !isBoolean(x.typ) {
606 check.invalidArg(x.pos(), "%s is not a boolean constant", x)
607 return
608 }
609 if x.val.Kind() != constant.Bool {
610 check.errorf(x.pos(), "internal error: value of %s should be a boolean constant", x)
611 return
612 }
613 if !constant.BoolVal(x.val) {
614 check.errorf(call.Pos(), "%v failed", call)
615
616 }
617
618
619 case _Trace:
620
621
622
623
624
625 if nargs == 0 {
626 check.dump("%v: trace() without arguments", call.Pos())
627 x.mode = novalue
628 break
629 }
630 var t operand
631 x1 := x
632 for _, arg := range call.Args {
633 check.rawExpr(x1, arg, nil)
634 check.dump("%v: %s", x1.pos(), x1)
635 x1 = &t
636 }
637
638
639 default:
640 unreachable()
641 }
642
643 return true
644 }
645
646
647
648 func makeSig(res Type, args ...Type) *Signature {
649 list := make([]*Var, len(args))
650 for i, param := range args {
651 list[i] = NewVar(token.NoPos, nil, "", Default(param))
652 }
653 params := NewTuple(list...)
654 var result *Tuple
655 if res != nil {
656 assert(!isUntyped(res))
657 result = NewTuple(NewVar(token.NoPos, nil, "", res))
658 }
659 return &Signature{params: params, results: result}
660 }
661
662
663
664
665 func implicitArrayDeref(typ Type) Type {
666 if p, ok := typ.(*Pointer); ok {
667 if a, ok := p.base.Underlying().(*Array); ok {
668 return a
669 }
670 }
671 return typ
672 }
673
674
675 func unparen(e ast.Expr) ast.Expr {
676 for {
677 p, ok := e.(*ast.ParenExpr)
678 if !ok {
679 return e
680 }
681 e = p.X
682 }
683 }
684
View as plain text