1// Copyright 2014 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 5package types 6 7import ( 8 "fmt" 9 "go/ast" 10 "go/constant" 11 "go/token" 12 "internal/buildcfg" 13 . "internal/types/errors" 14) 15 16func (check *Checker) declare(scope *Scope, id *ast.Ident, obj Object, pos token.Pos) { 17 // spec: "The blank identifier, represented by the underscore 18 // character _, may be used in a declaration like any other 19 // identifier but the declaration does not introduce a new 20 // binding." 21 if obj.Name() != "_" { 22 if alt := scope.Insert(obj); alt != nil { 23 err := check.newError(DuplicateDecl) 24 err.addf(obj, "%s redeclared in this block", obj.Name()) 25 err.addAltDecl(alt) 26 err.report() 27 return 28 } 29 obj.setScopePos(pos) 30 } 31 if id != nil { 32 check.recordDef(id, obj) 33 } 34} 35 36// pathString returns a string of the form a->b-> ... ->g for a path [a, b, ... g]. 37func pathString(path []Object) string { 38 var s string 39 for i, p := range path { 40 if i > 0 { 41 s += "->" 42 } 43 s += p.Name() 44 } 45 return s 46} 47 48// objDecl type-checks the declaration of obj in its respective (file) environment. 49// For the meaning of def, see Checker.definedType, in typexpr.go. 50func (check *Checker) objDecl(obj Object, def *TypeName) { 51 if check.conf._Trace && obj.Type() == nil { 52 if check.indent == 0 { 53 fmt.Println() // empty line between top-level objects for readability 54 } 55 check.trace(obj.Pos(), "-- checking %s (%s, objPath = %s)", obj, obj.color(), pathString(check.objPath)) 56 check.indent++ 57 defer func() { 58 check.indent-- 59 check.trace(obj.Pos(), "=> %s (%s)", obj, obj.color()) 60 }() 61 } 62 63 // Checking the declaration of obj means inferring its type 64 // (and possibly its value, for constants). 65 // An object's type (and thus the object) may be in one of 66 // three states which are expressed by colors: 67 // 68 // - an object whose type is not yet known is painted white (initial color) 69 // - an object whose type is in the process of being inferred is painted grey 70 // - an object whose type is fully inferred is painted black 71 // 72 // During type inference, an object's color changes from white to grey 73 // to black (pre-declared objects are painted black from the start). 74 // A black object (i.e., its type) can only depend on (refer to) other black 75 // ones. White and grey objects may depend on white and black objects. 76 // A dependency on a grey object indicates a cycle which may or may not be 77 // valid. 78 // 79 // When objects turn grey, they are pushed on the object path (a stack); 80 // they are popped again when they turn black. Thus, if a grey object (a 81 // cycle) is encountered, it is on the object path, and all the objects 82 // it depends on are the remaining objects on that path. Color encoding 83 // is such that the color value of a grey object indicates the index of 84 // that object in the object path. 85 86 // During type-checking, white objects may be assigned a type without 87 // traversing through objDecl; e.g., when initializing constants and 88 // variables. Update the colors of those objects here (rather than 89 // everywhere where we set the type) to satisfy the color invariants. 90 if obj.color() == white && obj.Type() != nil { 91 obj.setColor(black) 92 return 93 } 94 95 switch obj.color() { 96 case white: 97 assert(obj.Type() == nil) 98 // All color values other than white and black are considered grey. 99 // Because black and white are < grey, all values >= grey are grey. 100 // Use those values to encode the object's index into the object path. 101 obj.setColor(grey + color(check.push(obj))) 102 defer func() { 103 check.pop().setColor(black) 104 }() 105 106 case black: 107 assert(obj.Type() != nil) 108 return 109 110 default: 111 // Color values other than white or black are considered grey. 112 fallthrough 113 114 case grey: 115 // We have a (possibly invalid) cycle. 116 // In the existing code, this is marked by a non-nil type 117 // for the object except for constants and variables whose 118 // type may be non-nil (known), or nil if it depends on the 119 // not-yet known initialization value. 120 // In the former case, set the type to Typ[Invalid] because 121 // we have an initialization cycle. The cycle error will be 122 // reported later, when determining initialization order. 123 // TODO(gri) Report cycle here and simplify initialization 124 // order code. 125 switch obj := obj.(type) { 126 case *Const: 127 if !check.validCycle(obj) || obj.typ == nil { 128 obj.typ = Typ[Invalid] 129 } 130 131 case *Var: 132 if !check.validCycle(obj) || obj.typ == nil { 133 obj.typ = Typ[Invalid] 134 } 135 136 case *TypeName: 137 if !check.validCycle(obj) { 138 // break cycle 139 // (without this, calling underlying() 140 // below may lead to an endless loop 141 // if we have a cycle for a defined 142 // (*Named) type) 143 obj.typ = Typ[Invalid] 144 } 145 146 case *Func: 147 if !check.validCycle(obj) { 148 // Don't set obj.typ to Typ[Invalid] here 149 // because plenty of code type-asserts that 150 // functions have a *Signature type. Grey 151 // functions have their type set to an empty 152 // signature which makes it impossible to 153 // initialize a variable with the function. 154 } 155 156 default: 157 panic("unreachable") 158 } 159 assert(obj.Type() != nil) 160 return 161 } 162 163 d := check.objMap[obj] 164 if d == nil { 165 check.dump("%v: %s should have been declared", obj.Pos(), obj) 166 panic("unreachable") 167 } 168 169 // save/restore current environment and set up object environment 170 defer func(env environment) { 171 check.environment = env 172 }(check.environment) 173 check.environment = environment{ 174 scope: d.file, 175 } 176 177 // Const and var declarations must not have initialization 178 // cycles. We track them by remembering the current declaration 179 // in check.decl. Initialization expressions depending on other 180 // consts, vars, or functions, add dependencies to the current 181 // check.decl. 182 switch obj := obj.(type) { 183 case *Const: 184 check.decl = d // new package-level const decl 185 check.constDecl(obj, d.vtyp, d.init, d.inherited) 186 case *Var: 187 check.decl = d // new package-level var decl 188 check.varDecl(obj, d.lhs, d.vtyp, d.init) 189 case *TypeName: 190 // invalid recursive types are detected via path 191 check.typeDecl(obj, d.tdecl, def) 192 check.collectMethods(obj) // methods can only be added to top-level types 193 case *Func: 194 // functions may be recursive - no need to track dependencies 195 check.funcDecl(obj, d) 196 default: 197 panic("unreachable") 198 } 199} 200 201// validCycle checks if the cycle starting with obj is valid and 202// reports an error if it is not. 203func (check *Checker) validCycle(obj Object) (valid bool) { 204 // The object map contains the package scope objects and the non-interface methods. 205 if debug { 206 info := check.objMap[obj] 207 inObjMap := info != nil && (info.fdecl == nil || info.fdecl.Recv == nil) // exclude methods 208 isPkgObj := obj.Parent() == check.pkg.scope 209 if isPkgObj != inObjMap { 210 check.dump("%v: inconsistent object map for %s (isPkgObj = %v, inObjMap = %v)", obj.Pos(), obj, isPkgObj, inObjMap) 211 panic("unreachable") 212 } 213 } 214 215 // Count cycle objects. 216 assert(obj.color() >= grey) 217 start := obj.color() - grey // index of obj in objPath 218 cycle := check.objPath[start:] 219 tparCycle := false // if set, the cycle is through a type parameter list 220 nval := 0 // number of (constant or variable) values in the cycle; valid if !generic 221 ndef := 0 // number of type definitions in the cycle; valid if !generic 222loop: 223 for _, obj := range cycle { 224 switch obj := obj.(type) { 225 case *Const, *Var: 226 nval++ 227 case *TypeName: 228 // If we reach a generic type that is part of a cycle 229 // and we are in a type parameter list, we have a cycle 230 // through a type parameter list, which is invalid. 231 if check.inTParamList && isGeneric(obj.typ) { 232 tparCycle = true 233 break loop 234 } 235 236 // Determine if the type name is an alias or not. For 237 // package-level objects, use the object map which 238 // provides syntactic information (which doesn't rely 239 // on the order in which the objects are set up). For 240 // local objects, we can rely on the order, so use 241 // the object's predicate. 242 // TODO(gri) It would be less fragile to always access 243 // the syntactic information. We should consider storing 244 // this information explicitly in the object. 245 var alias bool 246 if check.conf._EnableAlias { 247 alias = obj.IsAlias() 248 } else { 249 if d := check.objMap[obj]; d != nil { 250 alias = d.tdecl.Assign.IsValid() // package-level object 251 } else { 252 alias = obj.IsAlias() // function local object 253 } 254 } 255 if !alias { 256 ndef++ 257 } 258 case *Func: 259 // ignored for now 260 default: 261 panic("unreachable") 262 } 263 } 264 265 if check.conf._Trace { 266 check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle)) 267 if tparCycle { 268 check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list") 269 } else { 270 check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef) 271 } 272 defer func() { 273 if valid { 274 check.trace(obj.Pos(), "=> cycle is valid") 275 } else { 276 check.trace(obj.Pos(), "=> error: cycle is invalid") 277 } 278 }() 279 } 280 281 if !tparCycle { 282 // A cycle involving only constants and variables is invalid but we 283 // ignore them here because they are reported via the initialization 284 // cycle check. 285 if nval == len(cycle) { 286 return true 287 } 288 289 // A cycle involving only types (and possibly functions) must have at least 290 // one type definition to be permitted: If there is no type definition, we 291 // have a sequence of alias type names which will expand ad infinitum. 292 if nval == 0 && ndef > 0 { 293 return true 294 } 295 } 296 297 check.cycleError(cycle, firstInSrc(cycle)) 298 return false 299} 300 301// cycleError reports a declaration cycle starting with the object at cycle[start]. 302func (check *Checker) cycleError(cycle []Object, start int) { 303 // name returns the (possibly qualified) object name. 304 // This is needed because with generic types, cycles 305 // may refer to imported types. See go.dev/issue/50788. 306 // TODO(gri) Thus functionality is used elsewhere. Factor it out. 307 name := func(obj Object) string { 308 return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name() 309 } 310 311 obj := cycle[start] 312 objName := name(obj) 313 // If obj is a type alias, mark it as valid (not broken) in order to avoid follow-on errors. 314 tname, _ := obj.(*TypeName) 315 if tname != nil && tname.IsAlias() { 316 // If we use Alias nodes, it is initialized with Typ[Invalid]. 317 // TODO(gri) Adjust this code if we initialize with nil. 318 if !check.conf._EnableAlias { 319 check.validAlias(tname, Typ[Invalid]) 320 } 321 } 322 323 // report a more concise error for self references 324 if len(cycle) == 1 { 325 if tname != nil { 326 check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName) 327 } else { 328 check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName) 329 } 330 return 331 } 332 333 err := check.newError(InvalidDeclCycle) 334 if tname != nil { 335 err.addf(obj, "invalid recursive type %s", objName) 336 } else { 337 err.addf(obj, "invalid cycle in declaration of %s", objName) 338 } 339 i := start 340 for range cycle { 341 err.addf(obj, "%s refers to", objName) 342 i++ 343 if i >= len(cycle) { 344 i = 0 345 } 346 obj = cycle[i] 347 objName = name(obj) 348 } 349 err.addf(obj, "%s", objName) 350 err.report() 351} 352 353// firstInSrc reports the index of the object with the "smallest" 354// source position in path. path must not be empty. 355func firstInSrc(path []Object) int { 356 fst, pos := 0, path[0].Pos() 357 for i, t := range path[1:] { 358 if cmpPos(t.Pos(), pos) < 0 { 359 fst, pos = i+1, t.Pos() 360 } 361 } 362 return fst 363} 364 365type ( 366 decl interface { 367 node() ast.Node 368 } 369 370 importDecl struct{ spec *ast.ImportSpec } 371 constDecl struct { 372 spec *ast.ValueSpec 373 iota int 374 typ ast.Expr 375 init []ast.Expr 376 inherited bool 377 } 378 varDecl struct{ spec *ast.ValueSpec } 379 typeDecl struct{ spec *ast.TypeSpec } 380 funcDecl struct{ decl *ast.FuncDecl } 381) 382 383func (d importDecl) node() ast.Node { return d.spec } 384func (d constDecl) node() ast.Node { return d.spec } 385func (d varDecl) node() ast.Node { return d.spec } 386func (d typeDecl) node() ast.Node { return d.spec } 387func (d funcDecl) node() ast.Node { return d.decl } 388 389func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) { 390 for _, d := range decls { 391 check.walkDecl(d, f) 392 } 393} 394 395func (check *Checker) walkDecl(d ast.Decl, f func(decl)) { 396 switch d := d.(type) { 397 case *ast.BadDecl: 398 // ignore 399 case *ast.GenDecl: 400 var last *ast.ValueSpec // last ValueSpec with type or init exprs seen 401 for iota, s := range d.Specs { 402 switch s := s.(type) { 403 case *ast.ImportSpec: 404 f(importDecl{s}) 405 case *ast.ValueSpec: 406 switch d.Tok { 407 case token.CONST: 408 // determine which initialization expressions to use 409 inherited := true 410 switch { 411 case s.Type != nil || len(s.Values) > 0: 412 last = s 413 inherited = false 414 case last == nil: 415 last = new(ast.ValueSpec) // make sure last exists 416 inherited = false 417 } 418 check.arityMatch(s, last) 419 f(constDecl{spec: s, iota: iota, typ: last.Type, init: last.Values, inherited: inherited}) 420 case token.VAR: 421 check.arityMatch(s, nil) 422 f(varDecl{s}) 423 default: 424 check.errorf(s, InvalidSyntaxTree, "invalid token %s", d.Tok) 425 } 426 case *ast.TypeSpec: 427 f(typeDecl{s}) 428 default: 429 check.errorf(s, InvalidSyntaxTree, "unknown ast.Spec node %T", s) 430 } 431 } 432 case *ast.FuncDecl: 433 f(funcDecl{d}) 434 default: 435 check.errorf(d, InvalidSyntaxTree, "unknown ast.Decl node %T", d) 436 } 437} 438 439func (check *Checker) constDecl(obj *Const, typ, init ast.Expr, inherited bool) { 440 assert(obj.typ == nil) 441 442 // use the correct value of iota 443 defer func(iota constant.Value, errpos positioner) { 444 check.iota = iota 445 check.errpos = errpos 446 }(check.iota, check.errpos) 447 check.iota = obj.val 448 check.errpos = nil 449 450 // provide valid constant value under all circumstances 451 obj.val = constant.MakeUnknown() 452 453 // determine type, if any 454 if typ != nil { 455 t := check.typ(typ) 456 if !isConstType(t) { 457 // don't report an error if the type is an invalid C (defined) type 458 // (go.dev/issue/22090) 459 if isValid(under(t)) { 460 check.errorf(typ, InvalidConstType, "invalid constant type %s", t) 461 } 462 obj.typ = Typ[Invalid] 463 return 464 } 465 obj.typ = t 466 } 467 468 // check initialization 469 var x operand 470 if init != nil { 471 if inherited { 472 // The initialization expression is inherited from a previous 473 // constant declaration, and (error) positions refer to that 474 // expression and not the current constant declaration. Use 475 // the constant identifier position for any errors during 476 // init expression evaluation since that is all we have 477 // (see issues go.dev/issue/42991, go.dev/issue/42992). 478 check.errpos = atPos(obj.pos) 479 } 480 check.expr(nil, &x, init) 481 } 482 check.initConst(obj, &x) 483} 484 485func (check *Checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) { 486 assert(obj.typ == nil) 487 488 // determine type, if any 489 if typ != nil { 490 obj.typ = check.varType(typ) 491 // We cannot spread the type to all lhs variables if there 492 // are more than one since that would mark them as checked 493 // (see Checker.objDecl) and the assignment of init exprs, 494 // if any, would not be checked. 495 // 496 // TODO(gri) If we have no init expr, we should distribute 497 // a given type otherwise we need to re-evaluate the type 498 // expr for each lhs variable, leading to duplicate work. 499 } 500 501 // check initialization 502 if init == nil { 503 if typ == nil { 504 // error reported before by arityMatch 505 obj.typ = Typ[Invalid] 506 } 507 return 508 } 509 510 if lhs == nil || len(lhs) == 1 { 511 assert(lhs == nil || lhs[0] == obj) 512 var x operand 513 check.expr(newTarget(obj.typ, obj.name), &x, init) 514 check.initVar(obj, &x, "variable declaration") 515 return 516 } 517 518 if debug { 519 // obj must be one of lhs 520 found := false 521 for _, lhs := range lhs { 522 if obj == lhs { 523 found = true 524 break 525 } 526 } 527 if !found { 528 panic("inconsistent lhs") 529 } 530 } 531 532 // We have multiple variables on the lhs and one init expr. 533 // Make sure all variables have been given the same type if 534 // one was specified, otherwise they assume the type of the 535 // init expression values (was go.dev/issue/15755). 536 if typ != nil { 537 for _, lhs := range lhs { 538 lhs.typ = obj.typ 539 } 540 } 541 542 check.initVars(lhs, []ast.Expr{init}, nil) 543} 544 545// isImportedConstraint reports whether typ is an imported type constraint. 546func (check *Checker) isImportedConstraint(typ Type) bool { 547 named := asNamed(typ) 548 if named == nil || named.obj.pkg == check.pkg || named.obj.pkg == nil { 549 return false 550 } 551 u, _ := named.under().(*Interface) 552 return u != nil && !u.IsMethodSet() 553} 554 555func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *TypeName) { 556 assert(obj.typ == nil) 557 558 // Only report a version error if we have not reported one already. 559 versionErr := false 560 561 var rhs Type 562 check.later(func() { 563 if t := asNamed(obj.typ); t != nil { // type may be invalid 564 check.validType(t) 565 } 566 // If typ is local, an error was already reported where typ is specified/defined. 567 _ = !versionErr && check.isImportedConstraint(rhs) && check.verifyVersionf(tdecl.Type, go1_18, "using type constraint %s", rhs) 568 }).describef(obj, "validType(%s)", obj.Name()) 569 570 // First type parameter, or nil. 571 var tparam0 *ast.Field 572 if tdecl.TypeParams.NumFields() > 0 { 573 tparam0 = tdecl.TypeParams.List[0] 574 } 575 576 // alias declaration 577 if tdecl.Assign.IsValid() { 578 // Report highest version requirement first so that fixing a version issue 579 // avoids possibly two -lang changes (first to Go 1.9 and then to Go 1.23). 580 if !versionErr && tparam0 != nil && !check.verifyVersionf(tparam0, go1_23, "generic type alias") { 581 versionErr = true 582 } 583 if !versionErr && !check.verifyVersionf(atPos(tdecl.Assign), go1_9, "type alias") { 584 versionErr = true 585 } 586 587 if check.conf._EnableAlias { 588 // TODO(gri) Should be able to use nil instead of Typ[Invalid] to mark 589 // the alias as incomplete. Currently this causes problems 590 // with certain cycles. Investigate. 591 // 592 // NOTE(adonovan): to avoid the Invalid being prematurely observed 593 // by (e.g.) a var whose type is an unfinished cycle, 594 // Unalias does not memoize if Invalid. Perhaps we should use a 595 // special sentinel distinct from Invalid. 596 alias := check.newAlias(obj, Typ[Invalid]) 597 setDefType(def, alias) 598 599 // handle type parameters even if not allowed (Alias type is supported) 600 if tparam0 != nil { 601 if !versionErr && !buildcfg.Experiment.AliasTypeParams { 602 check.error(tdecl, UnsupportedFeature, "generic type alias requires GOEXPERIMENT=aliastypeparams") 603 versionErr = true 604 } 605 check.openScope(tdecl, "type parameters") 606 defer check.closeScope() 607 check.collectTypeParams(&alias.tparams, tdecl.TypeParams) 608 } 609 610 rhs = check.definedType(tdecl.Type, obj) 611 assert(rhs != nil) 612 alias.fromRHS = rhs 613 Unalias(alias) // resolve alias.actual 614 } else { 615 // With Go1.23, the default behavior is to use Alias nodes, 616 // reflected by check.enableAlias. Signal non-default behavior. 617 // 618 // TODO(gri) Testing runs tests in both modes. Do we need to exclude 619 // tracking of non-default behavior for tests? 620 gotypesalias.IncNonDefault() 621 622 if !versionErr && tparam0 != nil { 623 check.error(tdecl, UnsupportedFeature, "generic type alias requires GODEBUG=gotypesalias=1 or unset") 624 versionErr = true 625 } 626 627 check.brokenAlias(obj) 628 rhs = check.typ(tdecl.Type) 629 check.validAlias(obj, rhs) 630 } 631 return 632 } 633 634 // type definition or generic type declaration 635 if !versionErr && tparam0 != nil && !check.verifyVersionf(tparam0, go1_18, "type parameter") { 636 versionErr = true 637 } 638 639 named := check.newNamed(obj, nil, nil) 640 setDefType(def, named) 641 642 if tdecl.TypeParams != nil { 643 check.openScope(tdecl, "type parameters") 644 defer check.closeScope() 645 check.collectTypeParams(&named.tparams, tdecl.TypeParams) 646 } 647 648 // determine underlying type of named 649 rhs = check.definedType(tdecl.Type, obj) 650 assert(rhs != nil) 651 named.fromRHS = rhs 652 653 // If the underlying type was not set while type-checking the right-hand 654 // side, it is invalid and an error should have been reported elsewhere. 655 if named.underlying == nil { 656 named.underlying = Typ[Invalid] 657 } 658 659 // Disallow a lone type parameter as the RHS of a type declaration (go.dev/issue/45639). 660 // We don't need this restriction anymore if we make the underlying type of a type 661 // parameter its constraint interface: if the RHS is a lone type parameter, we will 662 // use its underlying type (like we do for any RHS in a type declaration), and its 663 // underlying type is an interface and the type declaration is well defined. 664 if isTypeParam(rhs) { 665 check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration") 666 named.underlying = Typ[Invalid] 667 } 668} 669 670func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList) { 671 var tparams []*TypeParam 672 // Declare type parameters up-front, with empty interface as type bound. 673 // The scope of type parameters starts at the beginning of the type parameter 674 // list (so we can have mutually recursive parameterized interfaces). 675 scopePos := list.Pos() 676 for _, f := range list.List { 677 tparams = check.declareTypeParams(tparams, f.Names, scopePos) 678 } 679 680 // Set the type parameters before collecting the type constraints because 681 // the parameterized type may be used by the constraints (go.dev/issue/47887). 682 // Example: type T[P T[P]] interface{} 683 *dst = bindTParams(tparams) 684 685 // Signal to cycle detection that we are in a type parameter list. 686 // We can only be inside one type parameter list at any given time: 687 // function closures may appear inside a type parameter list but they 688 // cannot be generic, and their bodies are processed in delayed and 689 // sequential fashion. Note that with each new declaration, we save 690 // the existing environment and restore it when done; thus inTPList is 691 // true exactly only when we are in a specific type parameter list. 692 assert(!check.inTParamList) 693 check.inTParamList = true 694 defer func() { 695 check.inTParamList = false 696 }() 697 698 index := 0 699 for _, f := range list.List { 700 var bound Type 701 // NOTE: we may be able to assert that f.Type != nil here, but this is not 702 // an invariant of the AST, so we are cautious. 703 if f.Type != nil { 704 bound = check.bound(f.Type) 705 if isTypeParam(bound) { 706 // We may be able to allow this since it is now well-defined what 707 // the underlying type and thus type set of a type parameter is. 708 // But we may need some additional form of cycle detection within 709 // type parameter lists. 710 check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint") 711 bound = Typ[Invalid] 712 } 713 } else { 714 bound = Typ[Invalid] 715 } 716 for i := range f.Names { 717 tparams[index+i].bound = bound 718 } 719 index += len(f.Names) 720 } 721} 722 723func (check *Checker) bound(x ast.Expr) Type { 724 // A type set literal of the form ~T and A|B may only appear as constraint; 725 // embed it in an implicit interface so that only interface type-checking 726 // needs to take care of such type expressions. 727 wrap := false 728 switch op := x.(type) { 729 case *ast.UnaryExpr: 730 wrap = op.Op == token.TILDE 731 case *ast.BinaryExpr: 732 wrap = op.Op == token.OR 733 } 734 if wrap { 735 x = &ast.InterfaceType{Methods: &ast.FieldList{List: []*ast.Field{{Type: x}}}} 736 t := check.typ(x) 737 // mark t as implicit interface if all went well 738 if t, _ := t.(*Interface); t != nil { 739 t.implicit = true 740 } 741 return t 742 } 743 return check.typ(x) 744} 745 746func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident, scopePos token.Pos) []*TypeParam { 747 // Use Typ[Invalid] for the type constraint to ensure that a type 748 // is present even if the actual constraint has not been assigned 749 // yet. 750 // TODO(gri) Need to systematically review all uses of type parameter 751 // constraints to make sure we don't rely on them if they 752 // are not properly set yet. 753 for _, name := range names { 754 tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil) 755 tpar := check.newTypeParam(tname, Typ[Invalid]) // assigns type to tpar as a side-effect 756 check.declare(check.scope, name, tname, scopePos) 757 tparams = append(tparams, tpar) 758 } 759 760 if check.conf._Trace && len(names) > 0 { 761 check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):]) 762 } 763 764 return tparams 765} 766 767func (check *Checker) collectMethods(obj *TypeName) { 768 // get associated methods 769 // (Checker.collectObjects only collects methods with non-blank names; 770 // Checker.resolveBaseTypeName ensures that obj is not an alias name 771 // if it has attached methods.) 772 methods := check.methods[obj] 773 if methods == nil { 774 return 775 } 776 delete(check.methods, obj) 777 assert(!check.objMap[obj].tdecl.Assign.IsValid()) // don't use TypeName.IsAlias (requires fully set up object) 778 779 // use an objset to check for name conflicts 780 var mset objset 781 782 // spec: "If the base type is a struct type, the non-blank method 783 // and field names must be distinct." 784 base := asNamed(obj.typ) // shouldn't fail but be conservative 785 if base != nil { 786 assert(base.TypeArgs().Len() == 0) // collectMethods should not be called on an instantiated type 787 788 // See go.dev/issue/52529: we must delay the expansion of underlying here, as 789 // base may not be fully set-up. 790 check.later(func() { 791 check.checkFieldUniqueness(base) 792 }).describef(obj, "verifying field uniqueness for %v", base) 793 794 // Checker.Files may be called multiple times; additional package files 795 // may add methods to already type-checked types. Add pre-existing methods 796 // so that we can detect redeclarations. 797 for i := 0; i < base.NumMethods(); i++ { 798 m := base.Method(i) 799 assert(m.name != "_") 800 assert(mset.insert(m) == nil) 801 } 802 } 803 804 // add valid methods 805 for _, m := range methods { 806 // spec: "For a base type, the non-blank names of methods bound 807 // to it must be unique." 808 assert(m.name != "_") 809 if alt := mset.insert(m); alt != nil { 810 if alt.Pos().IsValid() { 811 check.errorf(m, DuplicateMethod, "method %s.%s already declared at %v", obj.Name(), m.name, alt.Pos()) 812 } else { 813 check.errorf(m, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name) 814 } 815 continue 816 } 817 818 if base != nil { 819 base.AddMethod(m) 820 } 821 } 822} 823 824func (check *Checker) checkFieldUniqueness(base *Named) { 825 if t, _ := base.under().(*Struct); t != nil { 826 var mset objset 827 for i := 0; i < base.NumMethods(); i++ { 828 m := base.Method(i) 829 assert(m.name != "_") 830 assert(mset.insert(m) == nil) 831 } 832 833 // Check that any non-blank field names of base are distinct from its 834 // method names. 835 for _, fld := range t.fields { 836 if fld.name != "_" { 837 if alt := mset.insert(fld); alt != nil { 838 // Struct fields should already be unique, so we should only 839 // encounter an alternate via collision with a method name. 840 _ = alt.(*Func) 841 842 // For historical consistency, we report the primary error on the 843 // method, and the alt decl on the field. 844 err := check.newError(DuplicateFieldAndMethod) 845 err.addf(alt, "field and method with the same name %s", fld.name) 846 err.addAltDecl(fld) 847 err.report() 848 } 849 } 850 } 851 } 852} 853 854func (check *Checker) funcDecl(obj *Func, decl *declInfo) { 855 assert(obj.typ == nil) 856 857 // func declarations cannot use iota 858 assert(check.iota == nil) 859 860 sig := new(Signature) 861 obj.typ = sig // guard against cycles 862 863 // Avoid cycle error when referring to method while type-checking the signature. 864 // This avoids a nuisance in the best case (non-parameterized receiver type) and 865 // since the method is not a type, we get an error. If we have a parameterized 866 // receiver type, instantiating the receiver type leads to the instantiation of 867 // its methods, and we don't want a cycle error in that case. 868 // TODO(gri) review if this is correct and/or whether we still need this? 869 saved := obj.color_ 870 obj.color_ = black 871 fdecl := decl.fdecl 872 check.funcType(sig, fdecl.Recv, fdecl.Type) 873 obj.color_ = saved 874 875 // Set the scope's extent to the complete "func (...) { ... }" 876 // so that Scope.Innermost works correctly. 877 sig.scope.pos = fdecl.Pos() 878 sig.scope.end = fdecl.End() 879 880 if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil { 881 check.softErrorf(fdecl.Name, BadDecl, "generic function is missing function body") 882 } 883 884 // function body must be type-checked after global declarations 885 // (functions implemented elsewhere have no body) 886 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { 887 check.later(func() { 888 check.funcBody(decl, obj.name, sig, fdecl.Body, nil) 889 }).describef(obj, "func %s", obj.name) 890 } 891} 892 893func (check *Checker) declStmt(d ast.Decl) { 894 pkg := check.pkg 895 896 check.walkDecl(d, func(d decl) { 897 switch d := d.(type) { 898 case constDecl: 899 top := len(check.delayed) 900 901 // declare all constants 902 lhs := make([]*Const, len(d.spec.Names)) 903 for i, name := range d.spec.Names { 904 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota))) 905 lhs[i] = obj 906 907 var init ast.Expr 908 if i < len(d.init) { 909 init = d.init[i] 910 } 911 912 check.constDecl(obj, d.typ, init, d.inherited) 913 } 914 915 // process function literals in init expressions before scope changes 916 check.processDelayed(top) 917 918 // spec: "The scope of a constant or variable identifier declared 919 // inside a function begins at the end of the ConstSpec or VarSpec 920 // (ShortVarDecl for short variable declarations) and ends at the 921 // end of the innermost containing block." 922 scopePos := d.spec.End() 923 for i, name := range d.spec.Names { 924 check.declare(check.scope, name, lhs[i], scopePos) 925 } 926 927 case varDecl: 928 top := len(check.delayed) 929 930 lhs0 := make([]*Var, len(d.spec.Names)) 931 for i, name := range d.spec.Names { 932 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) 933 } 934 935 // initialize all variables 936 for i, obj := range lhs0 { 937 var lhs []*Var 938 var init ast.Expr 939 switch len(d.spec.Values) { 940 case len(d.spec.Names): 941 // lhs and rhs match 942 init = d.spec.Values[i] 943 case 1: 944 // rhs is expected to be a multi-valued expression 945 lhs = lhs0 946 init = d.spec.Values[0] 947 default: 948 if i < len(d.spec.Values) { 949 init = d.spec.Values[i] 950 } 951 } 952 check.varDecl(obj, lhs, d.spec.Type, init) 953 if len(d.spec.Values) == 1 { 954 // If we have a single lhs variable we are done either way. 955 // If we have a single rhs expression, it must be a multi- 956 // valued expression, in which case handling the first lhs 957 // variable will cause all lhs variables to have a type 958 // assigned, and we are done as well. 959 if debug { 960 for _, obj := range lhs0 { 961 assert(obj.typ != nil) 962 } 963 } 964 break 965 } 966 } 967 968 // process function literals in init expressions before scope changes 969 check.processDelayed(top) 970 971 // declare all variables 972 // (only at this point are the variable scopes (parents) set) 973 scopePos := d.spec.End() // see constant declarations 974 for i, name := range d.spec.Names { 975 // see constant declarations 976 check.declare(check.scope, name, lhs0[i], scopePos) 977 } 978 979 case typeDecl: 980 obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil) 981 // spec: "The scope of a type identifier declared inside a function 982 // begins at the identifier in the TypeSpec and ends at the end of 983 // the innermost containing block." 984 scopePos := d.spec.Name.Pos() 985 check.declare(check.scope, d.spec.Name, obj, scopePos) 986 // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl) 987 obj.setColor(grey + color(check.push(obj))) 988 check.typeDecl(obj, d.spec, nil) 989 check.pop().setColor(black) 990 default: 991 check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node()) 992 } 993 }) 994} 995