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