github.com/rsc/go@v0.0.0-20150416155037-e040fd465409/src/go/types/typexpr.go (about) 1 // Copyright 2013 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 // This file implements type-checking of identifiers and type expressions. 6 7 package types 8 9 import ( 10 "go/ast" 11 "go/exact" 12 "go/token" 13 "sort" 14 "strconv" 15 ) 16 17 // ident type-checks identifier e and initializes x with the value or type of e. 18 // If an error occurred, x.mode is set to invalid. 19 // For the meaning of def and path, see check.typ, below. 20 // 21 func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeName) { 22 x.mode = invalid 23 x.expr = e 24 25 scope, obj := check.scope.LookupParent(e.Name) 26 if obj == nil { 27 if e.Name == "_" { 28 check.errorf(e.Pos(), "cannot use _ as value or type") 29 } else { 30 check.errorf(e.Pos(), "undeclared name: %s", e.Name) 31 } 32 return 33 } 34 check.recordUse(e, obj) 35 36 check.objDecl(obj, def, path) 37 typ := obj.Type() 38 assert(typ != nil) 39 40 // The object may be dot-imported: If so, remove its package from 41 // the map of unused dot imports for the respective file scope. 42 // (This code is only needed for dot-imports. Without them, 43 // we only have to mark variables, see *Var case below). 44 if pkg := obj.Pkg(); pkg != check.pkg && pkg != nil { 45 delete(check.unusedDotImports[scope], pkg) 46 } 47 48 switch obj := obj.(type) { 49 case *PkgName: 50 check.errorf(e.Pos(), "use of package %s not in selector", obj.name) 51 return 52 53 case *Const: 54 check.addDeclDep(obj) 55 if typ == Typ[Invalid] { 56 return 57 } 58 if obj == universeIota { 59 if check.iota == nil { 60 check.errorf(e.Pos(), "cannot use iota outside constant declaration") 61 return 62 } 63 x.val = check.iota 64 } else { 65 x.val = obj.val 66 } 67 assert(x.val != nil) 68 x.mode = constant 69 70 case *TypeName: 71 x.mode = typexpr 72 // check for cycle 73 // (it's ok to iterate forward because each named type appears at most once in path) 74 for i, prev := range path { 75 if prev == obj { 76 check.errorf(obj.pos, "illegal cycle in declaration of %s", obj.name) 77 // print cycle 78 for _, obj := range path[i:] { 79 check.errorf(obj.Pos(), "\t%s refers to", obj.Name()) // secondary error, \t indented 80 } 81 check.errorf(obj.Pos(), "\t%s", obj.Name()) 82 // maintain x.mode == typexpr despite error 83 typ = Typ[Invalid] 84 break 85 } 86 } 87 88 case *Var: 89 if obj.pkg == check.pkg { 90 obj.used = true 91 } 92 check.addDeclDep(obj) 93 if typ == Typ[Invalid] { 94 return 95 } 96 x.mode = variable 97 98 case *Func: 99 check.addDeclDep(obj) 100 x.mode = value 101 102 case *Builtin: 103 x.id = obj.id 104 x.mode = builtin 105 106 case *Nil: 107 x.mode = value 108 109 default: 110 unreachable() 111 } 112 113 x.typ = typ 114 } 115 116 // typExpr type-checks the type expression e and returns its type, or Typ[Invalid]. 117 // If def != nil, e is the type specification for the named type def, declared 118 // in a type declaration, and def.underlying will be set to the type of e before 119 // any components of e are type-checked. Path contains the path of named types 120 // referring to this type. 121 // 122 func (check *Checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) { 123 if trace { 124 check.trace(e.Pos(), "%s", e) 125 check.indent++ 126 defer func() { 127 check.indent-- 128 check.trace(e.Pos(), "=> %s", T) 129 }() 130 } 131 132 T = check.typExprInternal(e, def, path) 133 assert(isTyped(T)) 134 check.recordTypeAndValue(e, typexpr, T, nil) 135 136 return 137 } 138 139 func (check *Checker) typ(e ast.Expr) Type { 140 return check.typExpr(e, nil, nil) 141 } 142 143 // funcType type-checks a function or method type and returns its signature. 144 func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) *Signature { 145 scope := NewScope(check.scope, "function") 146 check.recordScope(ftyp, scope) 147 148 recvList, _ := check.collectParams(scope, recvPar, false) 149 params, variadic := check.collectParams(scope, ftyp.Params, true) 150 results, _ := check.collectParams(scope, ftyp.Results, false) 151 152 if recvPar != nil { 153 // recv parameter list present (may be empty) 154 // spec: "The receiver is specified via an extra parameter section preceeding the 155 // method name. That parameter section must declare a single parameter, the receiver." 156 var recv *Var 157 switch len(recvList) { 158 case 0: 159 check.error(recvPar.Pos(), "method is missing receiver") 160 recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below 161 default: 162 // more than one receiver 163 check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver") 164 fallthrough // continue with first receiver 165 case 1: 166 recv = recvList[0] 167 } 168 // spec: "The receiver type must be of the form T or *T where T is a type name." 169 // (ignore invalid types - error was reported before) 170 if t, _ := deref(recv.typ); t != Typ[Invalid] { 171 var err string 172 if T, _ := t.(*Named); T != nil { 173 // spec: "The type denoted by T is called the receiver base type; it must not 174 // be a pointer or interface type and it must be declared in the same package 175 // as the method." 176 if T.obj.pkg != check.pkg { 177 err = "type not defined in this package" 178 } else { 179 // TODO(gri) This is not correct if the underlying type is unknown yet. 180 switch u := T.underlying.(type) { 181 case *Basic: 182 // unsafe.Pointer is treated like a regular pointer 183 if u.kind == UnsafePointer { 184 err = "unsafe.Pointer" 185 } 186 case *Pointer, *Interface: 187 err = "pointer or interface type" 188 } 189 } 190 } else { 191 err = "basic or unnamed type" 192 } 193 if err != "" { 194 check.errorf(recv.pos, "invalid receiver %s (%s)", recv.typ, err) 195 // ok to continue 196 } 197 } 198 sig.recv = recv 199 } 200 201 sig.scope = scope 202 sig.params = NewTuple(params...) 203 sig.results = NewTuple(results...) 204 sig.variadic = variadic 205 206 return sig 207 } 208 209 // typExprInternal drives type checking of types. 210 // Must only be called by typExpr. 211 // 212 func (check *Checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type { 213 switch e := e.(type) { 214 case *ast.BadExpr: 215 // ignore - error reported before 216 217 case *ast.Ident: 218 var x operand 219 check.ident(&x, e, def, path) 220 221 switch x.mode { 222 case typexpr: 223 typ := x.typ 224 def.setUnderlying(typ) 225 return typ 226 case invalid: 227 // ignore - error reported before 228 case novalue: 229 check.errorf(x.pos(), "%s used as type", &x) 230 default: 231 check.errorf(x.pos(), "%s is not a type", &x) 232 } 233 234 case *ast.SelectorExpr: 235 var x operand 236 check.selector(&x, e) 237 238 switch x.mode { 239 case typexpr: 240 typ := x.typ 241 def.setUnderlying(typ) 242 return typ 243 case invalid: 244 // ignore - error reported before 245 case novalue: 246 check.errorf(x.pos(), "%s used as type", &x) 247 default: 248 check.errorf(x.pos(), "%s is not a type", &x) 249 } 250 251 case *ast.ParenExpr: 252 return check.typExpr(e.X, def, path) 253 254 case *ast.ArrayType: 255 if e.Len != nil { 256 typ := new(Array) 257 def.setUnderlying(typ) 258 typ.len = check.arrayLength(e.Len) 259 typ.elem = check.typExpr(e.Elt, nil, path) 260 return typ 261 262 } else { 263 typ := new(Slice) 264 def.setUnderlying(typ) 265 typ.elem = check.typ(e.Elt) 266 return typ 267 } 268 269 case *ast.StructType: 270 typ := new(Struct) 271 def.setUnderlying(typ) 272 check.structType(typ, e, path) 273 return typ 274 275 case *ast.StarExpr: 276 typ := new(Pointer) 277 def.setUnderlying(typ) 278 typ.base = check.typ(e.X) 279 return typ 280 281 case *ast.FuncType: 282 typ := new(Signature) 283 def.setUnderlying(typ) 284 check.funcType(typ, nil, e) 285 return typ 286 287 case *ast.InterfaceType: 288 typ := new(Interface) 289 def.setUnderlying(typ) 290 check.interfaceType(typ, e, def, path) 291 return typ 292 293 case *ast.MapType: 294 typ := new(Map) 295 def.setUnderlying(typ) 296 297 typ.key = check.typ(e.Key) 298 typ.elem = check.typ(e.Value) 299 300 // spec: "The comparison operators == and != must be fully defined 301 // for operands of the key type; thus the key type must not be a 302 // function, map, or slice." 303 // 304 // Delay this check because it requires fully setup types; 305 // it is safe to continue in any case (was issue 6667). 306 check.delay(func() { 307 if !Comparable(typ.key) { 308 check.errorf(e.Key.Pos(), "invalid map key type %s", typ.key) 309 } 310 }) 311 312 return typ 313 314 case *ast.ChanType: 315 typ := new(Chan) 316 def.setUnderlying(typ) 317 318 dir := SendRecv 319 switch e.Dir { 320 case ast.SEND | ast.RECV: 321 // nothing to do 322 case ast.SEND: 323 dir = SendOnly 324 case ast.RECV: 325 dir = RecvOnly 326 default: 327 check.invalidAST(e.Pos(), "unknown channel direction %d", e.Dir) 328 // ok to continue 329 } 330 331 typ.dir = dir 332 typ.elem = check.typ(e.Value) 333 return typ 334 335 default: 336 check.errorf(e.Pos(), "%s is not a type", e) 337 } 338 339 typ := Typ[Invalid] 340 def.setUnderlying(typ) 341 return typ 342 } 343 344 // typeOrNil type-checks the type expression (or nil value) e 345 // and returns the typ of e, or nil. 346 // If e is neither a type nor nil, typOrNil returns Typ[Invalid]. 347 // 348 func (check *Checker) typOrNil(e ast.Expr) Type { 349 var x operand 350 check.rawExpr(&x, e, nil) 351 switch x.mode { 352 case invalid: 353 // ignore - error reported before 354 case novalue: 355 check.errorf(x.pos(), "%s used as type", &x) 356 case typexpr: 357 return x.typ 358 case value: 359 if x.isNil() { 360 return nil 361 } 362 fallthrough 363 default: 364 check.errorf(x.pos(), "%s is not a type", &x) 365 } 366 return Typ[Invalid] 367 } 368 369 func (check *Checker) arrayLength(e ast.Expr) int64 { 370 var x operand 371 check.expr(&x, e) 372 if x.mode != constant { 373 if x.mode != invalid { 374 check.errorf(x.pos(), "array length %s must be constant", &x) 375 } 376 return 0 377 } 378 if !x.isInteger() { 379 check.errorf(x.pos(), "array length %s must be integer", &x) 380 return 0 381 } 382 n, ok := exact.Int64Val(x.val) 383 if !ok || n < 0 { 384 check.errorf(x.pos(), "invalid array length %s", &x) 385 return 0 386 } 387 return n 388 } 389 390 func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) { 391 if list == nil { 392 return 393 } 394 395 var named, anonymous bool 396 for i, field := range list.List { 397 ftype := field.Type 398 if t, _ := ftype.(*ast.Ellipsis); t != nil { 399 ftype = t.Elt 400 if variadicOk && i == len(list.List)-1 { 401 variadic = true 402 } else { 403 check.invalidAST(field.Pos(), "... not permitted") 404 // ignore ... and continue 405 } 406 } 407 typ := check.typ(ftype) 408 // The parser ensures that f.Tag is nil and we don't 409 // care if a constructed AST contains a non-nil tag. 410 if len(field.Names) > 0 { 411 // named parameter 412 for _, name := range field.Names { 413 if name.Name == "" { 414 check.invalidAST(name.Pos(), "anonymous parameter") 415 // ok to continue 416 } 417 par := NewParam(name.Pos(), check.pkg, name.Name, typ) 418 check.declare(scope, name, par) 419 params = append(params, par) 420 } 421 named = true 422 } else { 423 // anonymous parameter 424 par := NewParam(ftype.Pos(), check.pkg, "", typ) 425 check.recordImplicit(field, par) 426 params = append(params, par) 427 anonymous = true 428 } 429 } 430 431 if named && anonymous { 432 check.invalidAST(list.Pos(), "list contains both named and anonymous parameters") 433 // ok to continue 434 } 435 436 // For a variadic function, change the last parameter's type from T to []T. 437 if variadic && len(params) > 0 { 438 last := params[len(params)-1] 439 last.typ = &Slice{elem: last.typ} 440 } 441 442 return 443 } 444 445 func (check *Checker) declareInSet(oset *objset, pos token.Pos, obj Object) bool { 446 if alt := oset.insert(obj); alt != nil { 447 check.errorf(pos, "%s redeclared", obj.Name()) 448 check.reportAltDecl(alt) 449 return false 450 } 451 return true 452 } 453 454 func (check *Checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, def *Named, path []*TypeName) { 455 // empty interface: common case 456 if ityp.Methods == nil { 457 return 458 } 459 460 // The parser ensures that field tags are nil and we don't 461 // care if a constructed AST contains non-nil tags. 462 463 // use named receiver type if available (for better error messages) 464 var recvTyp Type = iface 465 if def != nil { 466 recvTyp = def 467 } 468 469 // Phase 1: Collect explicitly declared methods, the corresponding 470 // signature (AST) expressions, and the list of embedded 471 // type (AST) expressions. Do not resolve signatures or 472 // embedded types yet to avoid cycles referring to this 473 // interface. 474 475 var ( 476 mset objset 477 signatures []ast.Expr // list of corresponding method signatures 478 embedded []ast.Expr // list of embedded types 479 ) 480 for _, f := range ityp.Methods.List { 481 if len(f.Names) > 0 { 482 // The parser ensures that there's only one method 483 // and we don't care if a constructed AST has more. 484 name := f.Names[0] 485 pos := name.Pos() 486 // spec: "As with all method sets, in an interface type, 487 // each method must have a unique non-blank name." 488 if name.Name == "_" { 489 check.errorf(pos, "invalid method name _") 490 continue 491 } 492 // Don't type-check signature yet - use an 493 // empty signature now and update it later. 494 // Since we know the receiver, set it up now 495 // (required to avoid crash in ptrRecv; see 496 // e.g. test case for issue 6638). 497 // TODO(gri) Consider marking methods signatures 498 // as incomplete, for better error messages. See 499 // also the T4 and T5 tests in testdata/cycles2.src. 500 sig := new(Signature) 501 sig.recv = NewVar(pos, check.pkg, "", recvTyp) 502 m := NewFunc(pos, check.pkg, name.Name, sig) 503 if check.declareInSet(&mset, pos, m) { 504 iface.methods = append(iface.methods, m) 505 iface.allMethods = append(iface.allMethods, m) 506 signatures = append(signatures, f.Type) 507 check.recordDef(name, m) 508 } 509 } else { 510 // embedded type 511 embedded = append(embedded, f.Type) 512 } 513 } 514 515 // Phase 2: Resolve embedded interfaces. Because an interface must not 516 // embed itself (directly or indirectly), each embedded interface 517 // can be fully resolved without depending on any method of this 518 // interface (if there is a cycle or another error, the embedded 519 // type resolves to an invalid type and is ignored). 520 // In particular, the list of methods for each embedded interface 521 // must be complete (it cannot depend on this interface), and so 522 // those methods can be added to the list of all methods of this 523 // interface. 524 525 for _, e := range embedded { 526 pos := e.Pos() 527 typ := check.typExpr(e, nil, path) 528 named, _ := typ.(*Named) 529 if named == nil { 530 if typ != Typ[Invalid] { 531 check.invalidAST(pos, "%s is not named type", typ) 532 } 533 continue 534 } 535 // determine underlying (possibly incomplete) type 536 // by following its forward chain 537 u := underlying(named) 538 embed, _ := u.(*Interface) 539 if embed == nil { 540 if u != Typ[Invalid] { 541 check.errorf(pos, "%s is not an interface", named) 542 } 543 continue 544 } 545 iface.embeddeds = append(iface.embeddeds, named) 546 // collect embedded methods 547 for _, m := range embed.allMethods { 548 if check.declareInSet(&mset, pos, m) { 549 iface.allMethods = append(iface.allMethods, m) 550 } 551 } 552 } 553 554 // Phase 3: At this point all methods have been collected for this interface. 555 // It is now safe to type-check the signatures of all explicitly 556 // declared methods, even if they refer to this interface via a cycle 557 // and embed the methods of this interface in a parameter of interface 558 // type. 559 560 for i, m := range iface.methods { 561 expr := signatures[i] 562 typ := check.typ(expr) 563 sig, _ := typ.(*Signature) 564 if sig == nil { 565 if typ != Typ[Invalid] { 566 check.invalidAST(expr.Pos(), "%s is not a method signature", typ) 567 } 568 continue // keep method with empty method signature 569 } 570 // update signature, but keep recv that was set up before 571 old := m.typ.(*Signature) 572 sig.recv = old.recv 573 *old = *sig // update signature (don't replace it!) 574 } 575 576 // TODO(gri) The list of explicit methods is only sorted for now to 577 // produce the same Interface as NewInterface. We may be able to 578 // claim source order in the future. Revisit. 579 sort.Sort(byUniqueMethodName(iface.methods)) 580 581 // TODO(gri) The list of embedded types is only sorted for now to 582 // produce the same Interface as NewInterface. We may be able to 583 // claim source order in the future. Revisit. 584 sort.Sort(byUniqueTypeName(iface.embeddeds)) 585 586 sort.Sort(byUniqueMethodName(iface.allMethods)) 587 } 588 589 // byUniqueTypeName named type lists can be sorted by their unique type names. 590 type byUniqueTypeName []*Named 591 592 func (a byUniqueTypeName) Len() int { return len(a) } 593 func (a byUniqueTypeName) Less(i, j int) bool { return a[i].obj.Id() < a[j].obj.Id() } 594 func (a byUniqueTypeName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 595 596 // byUniqueMethodName method lists can be sorted by their unique method names. 597 type byUniqueMethodName []*Func 598 599 func (a byUniqueMethodName) Len() int { return len(a) } 600 func (a byUniqueMethodName) Less(i, j int) bool { return a[i].Id() < a[j].Id() } 601 func (a byUniqueMethodName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } 602 603 func (check *Checker) tag(t *ast.BasicLit) string { 604 if t != nil { 605 if t.Kind == token.STRING { 606 if val, err := strconv.Unquote(t.Value); err == nil { 607 return val 608 } 609 } 610 check.invalidAST(t.Pos(), "incorrect tag syntax: %q", t.Value) 611 } 612 return "" 613 } 614 615 func (check *Checker) structType(styp *Struct, e *ast.StructType, path []*TypeName) { 616 list := e.Fields 617 if list == nil { 618 return 619 } 620 621 // struct fields and tags 622 var fields []*Var 623 var tags []string 624 625 // for double-declaration checks 626 var fset objset 627 628 // current field typ and tag 629 var typ Type 630 var tag string 631 // anonymous != nil indicates an anonymous field. 632 add := func(field *ast.Field, ident *ast.Ident, anonymous *TypeName, pos token.Pos) { 633 if tag != "" && tags == nil { 634 tags = make([]string, len(fields)) 635 } 636 if tags != nil { 637 tags = append(tags, tag) 638 } 639 640 name := ident.Name 641 fld := NewField(pos, check.pkg, name, typ, anonymous != nil) 642 // spec: "Within a struct, non-blank field names must be unique." 643 if name == "_" || check.declareInSet(&fset, pos, fld) { 644 fields = append(fields, fld) 645 check.recordDef(ident, fld) 646 } 647 if anonymous != nil { 648 check.recordUse(ident, anonymous) 649 } 650 } 651 652 for _, f := range list.List { 653 typ = check.typExpr(f.Type, nil, path) 654 tag = check.tag(f.Tag) 655 if len(f.Names) > 0 { 656 // named fields 657 for _, name := range f.Names { 658 add(f, name, nil, name.Pos()) 659 } 660 } else { 661 // anonymous field 662 name := anonymousFieldIdent(f.Type) 663 pos := f.Type.Pos() 664 t, isPtr := deref(typ) 665 switch t := t.(type) { 666 case *Basic: 667 if t == Typ[Invalid] { 668 // error was reported before 669 continue 670 } 671 // unsafe.Pointer is treated like a regular pointer 672 if t.kind == UnsafePointer { 673 check.errorf(pos, "anonymous field type cannot be unsafe.Pointer") 674 continue 675 } 676 add(f, name, Universe.Lookup(t.name).(*TypeName), pos) 677 678 case *Named: 679 // spec: "An embedded type must be specified as a type name 680 // T or as a pointer to a non-interface type name *T, and T 681 // itself may not be a pointer type." 682 switch u := t.underlying.(type) { 683 case *Basic: 684 // unsafe.Pointer is treated like a regular pointer 685 if u.kind == UnsafePointer { 686 check.errorf(pos, "anonymous field type cannot be unsafe.Pointer") 687 continue 688 } 689 case *Pointer: 690 check.errorf(pos, "anonymous field type cannot be a pointer") 691 continue 692 case *Interface: 693 if isPtr { 694 check.errorf(pos, "anonymous field type cannot be a pointer to an interface") 695 continue 696 } 697 } 698 add(f, name, t.obj, pos) 699 700 default: 701 check.invalidAST(pos, "anonymous field type %s must be named", typ) 702 } 703 } 704 } 705 706 styp.fields = fields 707 styp.tags = tags 708 } 709 710 func anonymousFieldIdent(e ast.Expr) *ast.Ident { 711 switch e := e.(type) { 712 case *ast.Ident: 713 return e 714 case *ast.StarExpr: 715 return anonymousFieldIdent(e.X) 716 case *ast.SelectorExpr: 717 return e.Sel 718 } 719 return nil // invalid anonymous field 720 }