github.com/bir3/gocompiler@v0.3.205/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 *Named) { 57 if 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 d := check.objMap[obj]; d != nil { 253 alias = d.tdecl.Assign.IsValid() // package-level object 254 } else { 255 alias = obj.IsAlias() // function local object 256 } 257 if !alias { 258 ndef++ 259 } 260 case *Func: 261 // ignored for now 262 default: 263 unreachable() 264 } 265 } 266 267 if trace { 268 check.trace(obj.Pos(), "## cycle detected: objPath = %s->%s (len = %d)", pathString(cycle), obj.Name(), len(cycle)) 269 if tparCycle { 270 check.trace(obj.Pos(), "## cycle contains: generic type in a type parameter list") 271 } else { 272 check.trace(obj.Pos(), "## cycle contains: %d values, %d type definitions", nval, ndef) 273 } 274 defer func() { 275 if valid { 276 check.trace(obj.Pos(), "=> cycle is valid") 277 } else { 278 check.trace(obj.Pos(), "=> error: cycle is invalid") 279 } 280 }() 281 } 282 283 if !tparCycle { 284 // A cycle involving only constants and variables is invalid but we 285 // ignore them here because they are reported via the initialization 286 // cycle check. 287 if nval == len(cycle) { 288 return true 289 } 290 291 // A cycle involving only types (and possibly functions) must have at least 292 // one type definition to be permitted: If there is no type definition, we 293 // have a sequence of alias type names which will expand ad infinitum. 294 if nval == 0 && ndef > 0 { 295 return true 296 } 297 } 298 299 check.cycleError(cycle) 300 return false 301 } 302 303 // cycleError reports a declaration cycle starting with 304 // the object in cycle that is "first" in the source. 305 func (check *Checker) cycleError(cycle []Object) { 306 // name returns the (possibly qualified) object name. 307 // This is needed because with generic types, cycles 308 // may refer to imported types. See issue #50788. 309 // TODO(gri) Thus functionality is used elsewhere. Factor it out. 310 name := func(obj Object) string { 311 return packagePrefix(obj.Pkg(), check.qualifier) + obj.Name() 312 } 313 314 // TODO(gri) Should we start with the last (rather than the first) object in the cycle 315 // since that is the earliest point in the source where we start seeing the 316 // cycle? That would be more consistent with other error messages. 317 i := firstInSrc(cycle) 318 obj := cycle[i] 319 objName := name(obj) 320 // If obj is a type alias, mark it as valid (not broken) in order to avoid follow-on errors. 321 tname, _ := obj.(*TypeName) 322 if tname != nil && tname.IsAlias() { 323 check.validAlias(tname, Typ[Invalid]) 324 } 325 326 // report a more concise error for self references 327 if len(cycle) == 1 { 328 if tname != nil { 329 check.errorf(obj, InvalidDeclCycle, "invalid recursive type: %s refers to itself", objName) 330 } else { 331 check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration: %s refers to itself", objName) 332 } 333 return 334 } 335 336 if tname != nil { 337 check.errorf(obj, InvalidDeclCycle, "invalid recursive type %s", objName) 338 } else { 339 check.errorf(obj, InvalidDeclCycle, "invalid cycle in declaration of %s", objName) 340 } 341 for range cycle { 342 check.errorf(obj, InvalidDeclCycle, "\t%s refers to", objName) // secondary error, \t indented 343 i++ 344 if i >= len(cycle) { 345 i = 0 346 } 347 obj = cycle[i] 348 objName = name(obj) 349 } 350 check.errorf(obj, InvalidDeclCycle, "\t%s", objName) 351 } 352 353 // firstInSrc reports the index of the object with the "smallest" 354 // source position in path. path must not be empty. 355 func firstInSrc(path []Object) int { 356 fst, pos := 0, path[0].Pos() 357 for i, t := range path[1:] { 358 if t.Pos() < pos { 359 fst, pos = i+1, t.Pos() 360 } 361 } 362 return fst 363 } 364 365 type ( 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 383 func (d importDecl) node() ast.Node { return d.spec } 384 func (d constDecl) node() ast.Node { return d.spec } 385 func (d varDecl) node() ast.Node { return d.spec } 386 func (d typeDecl) node() ast.Node { return d.spec } 387 func (d funcDecl) node() ast.Node { return d.decl } 388 389 func (check *Checker) walkDecls(decls []ast.Decl, f func(decl)) { 390 for _, d := range decls { 391 check.walkDecl(d, f) 392 } 393 } 394 395 func (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 439 func (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 // (issue #22090) 459 if under(t) != Typ[Invalid] { 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 #42991, #42992). 478 check.errpos = atPos(obj.pos) 479 } 480 check.expr(&x, init) 481 } 482 check.initConst(obj, &x) 483 } 484 485 func (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-evalate 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(&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 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. 546 func (check *Checker) isImportedConstraint(typ Type) bool { 547 named, _ := typ.(*Named) 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 555 func (check *Checker) typeDecl(obj *TypeName, tdecl *ast.TypeSpec, def *Named) { 556 assert(obj.typ == nil) 557 558 var rhs Type 559 check.later(func() { 560 if t, _ := obj.typ.(*Named); t != nil { // type may be invalid 561 check.validType(t) 562 } 563 // If typ is local, an error was already reported where typ is specified/defined. 564 if check.isImportedConstraint(rhs) && !check.allowVersion(check.pkg, 1, 18) { 565 check.errorf(tdecl.Type, UnsupportedFeature, "using type constraint %s requires go1.18 or later", rhs) 566 } 567 }).describef(obj, "validType(%s)", obj.Name()) 568 569 alias := tdecl.Assign.IsValid() 570 if alias && tdecl.TypeParams.NumFields() != 0 { 571 // The parser will ensure this but we may still get an invalid AST. 572 // Complain and continue as regular type definition. 573 check.error(atPos(tdecl.Assign), BadDecl, "generic type cannot be alias") 574 alias = false 575 } 576 577 // alias declaration 578 if alias { 579 if !check.allowVersion(check.pkg, 1, 9) { 580 check.error(atPos(tdecl.Assign), UnsupportedFeature, "type aliases requires go1.9 or later") 581 } 582 583 check.brokenAlias(obj) 584 rhs = check.typ(tdecl.Type) 585 check.validAlias(obj, rhs) 586 return 587 } 588 589 // type definition or generic type declaration 590 named := check.newNamed(obj, nil, nil) 591 def.setUnderlying(named) 592 593 if tdecl.TypeParams != nil { 594 check.openScope(tdecl, "type parameters") 595 defer check.closeScope() 596 check.collectTypeParams(&named.tparams, tdecl.TypeParams) 597 } 598 599 // determine underlying type of named 600 rhs = check.definedType(tdecl.Type, named) 601 assert(rhs != nil) 602 named.fromRHS = rhs 603 604 // If the underlying type was not set while type-checking the right-hand 605 // side, it is invalid and an error should have been reported elsewhere. 606 if named.underlying == nil { 607 named.underlying = Typ[Invalid] 608 } 609 610 // Disallow a lone type parameter as the RHS of a type declaration (issue #45639). 611 // We don't need this restriction anymore if we make the underlying type of a type 612 // parameter its constraint interface: if the RHS is a lone type parameter, we will 613 // use its underlying type (like we do for any RHS in a type declaration), and its 614 // underlying type is an interface and the type declaration is well defined. 615 if isTypeParam(rhs) { 616 check.error(tdecl.Type, MisplacedTypeParam, "cannot use a type parameter as RHS in type declaration") 617 named.underlying = Typ[Invalid] 618 } 619 } 620 621 func (check *Checker) collectTypeParams(dst **TypeParamList, list *ast.FieldList) { 622 var tparams []*TypeParam 623 // Declare type parameters up-front, with empty interface as type bound. 624 // The scope of type parameters starts at the beginning of the type parameter 625 // list (so we can have mutually recursive parameterized interfaces). 626 for _, f := range list.List { 627 tparams = check.declareTypeParams(tparams, f.Names) 628 } 629 630 // Set the type parameters before collecting the type constraints because 631 // the parameterized type may be used by the constraints (issue #47887). 632 // Example: type T[P T[P]] interface{} 633 *dst = bindTParams(tparams) 634 635 // Signal to cycle detection that we are in a type parameter list. 636 // We can only be inside one type parameter list at any given time: 637 // function closures may appear inside a type parameter list but they 638 // cannot be generic, and their bodies are processed in delayed and 639 // sequential fashion. Note that with each new declaration, we save 640 // the existing environment and restore it when done; thus inTPList is 641 // true exactly only when we are in a specific type parameter list. 642 assert(!check.inTParamList) 643 check.inTParamList = true 644 defer func() { 645 check.inTParamList = false 646 }() 647 648 index := 0 649 for _, f := range list.List { 650 var bound Type 651 // NOTE: we may be able to assert that f.Type != nil here, but this is not 652 // an invariant of the AST, so we are cautious. 653 if f.Type != nil { 654 bound = check.bound(f.Type) 655 if isTypeParam(bound) { 656 // We may be able to allow this since it is now well-defined what 657 // the underlying type and thus type set of a type parameter is. 658 // But we may need some additional form of cycle detection within 659 // type parameter lists. 660 check.error(f.Type, MisplacedTypeParam, "cannot use a type parameter as constraint") 661 bound = Typ[Invalid] 662 } 663 } else { 664 bound = Typ[Invalid] 665 } 666 for i := range f.Names { 667 tparams[index+i].bound = bound 668 } 669 index += len(f.Names) 670 } 671 } 672 673 func (check *Checker) bound(x ast.Expr) Type { 674 // A type set literal of the form ~T and A|B may only appear as constraint; 675 // embed it in an implicit interface so that only interface type-checking 676 // needs to take care of such type expressions. 677 wrap := false 678 switch op := x.(type) { 679 case *ast.UnaryExpr: 680 wrap = op.Op == token.TILDE 681 case *ast.BinaryExpr: 682 wrap = op.Op == token.OR 683 } 684 if wrap { 685 x = &ast.InterfaceType{Methods: &ast.FieldList{List: []*ast.Field{{Type: x}}}} 686 t := check.typ(x) 687 // mark t as implicit interface if all went well 688 if t, _ := t.(*Interface); t != nil { 689 t.implicit = true 690 } 691 return t 692 } 693 return check.typ(x) 694 } 695 696 func (check *Checker) declareTypeParams(tparams []*TypeParam, names []*ast.Ident) []*TypeParam { 697 // Use Typ[Invalid] for the type constraint to ensure that a type 698 // is present even if the actual constraint has not been assigned 699 // yet. 700 // TODO(gri) Need to systematically review all uses of type parameter 701 // constraints to make sure we don't rely on them if they 702 // are not properly set yet. 703 for _, name := range names { 704 tname := NewTypeName(name.Pos(), check.pkg, name.Name, nil) 705 tpar := check.newTypeParam(tname, Typ[Invalid]) // assigns type to tpar as a side-effect 706 check.declare(check.scope, name, tname, check.scope.pos) // TODO(gri) check scope position 707 tparams = append(tparams, tpar) 708 } 709 710 if trace && len(names) > 0 { 711 check.trace(names[0].Pos(), "type params = %v", tparams[len(tparams)-len(names):]) 712 } 713 714 return tparams 715 } 716 717 func (check *Checker) collectMethods(obj *TypeName) { 718 // get associated methods 719 // (Checker.collectObjects only collects methods with non-blank names; 720 // Checker.resolveBaseTypeName ensures that obj is not an alias name 721 // if it has attached methods.) 722 methods := check.methods[obj] 723 if methods == nil { 724 return 725 } 726 delete(check.methods, obj) 727 assert(!check.objMap[obj].tdecl.Assign.IsValid()) // don't use TypeName.IsAlias (requires fully set up object) 728 729 // use an objset to check for name conflicts 730 var mset objset 731 732 // spec: "If the base type is a struct type, the non-blank method 733 // and field names must be distinct." 734 base, _ := obj.typ.(*Named) // shouldn't fail but be conservative 735 if base != nil { 736 assert(base.TypeArgs().Len() == 0) // collectMethods should not be called on an instantiated type 737 738 // See issue #52529: we must delay the expansion of underlying here, as 739 // base may not be fully set-up. 740 check.later(func() { 741 check.checkFieldUniqueness(base) 742 }).describef(obj, "verifying field uniqueness for %v", base) 743 744 // Checker.Files may be called multiple times; additional package files 745 // may add methods to already type-checked types. Add pre-existing methods 746 // so that we can detect redeclarations. 747 for i := 0; i < base.NumMethods(); i++ { 748 m := base.Method(i) 749 assert(m.name != "_") 750 assert(mset.insert(m) == nil) 751 } 752 } 753 754 // add valid methods 755 for _, m := range methods { 756 // spec: "For a base type, the non-blank names of methods bound 757 // to it must be unique." 758 assert(m.name != "_") 759 if alt := mset.insert(m); alt != nil { 760 if alt.Pos().IsValid() { 761 check.errorf(m, DuplicateMethod, "method %s.%s already declared at %s", obj.Name(), m.name, alt.Pos()) 762 } else { 763 check.errorf(m, DuplicateMethod, "method %s.%s already declared", obj.Name(), m.name) 764 } 765 continue 766 } 767 768 if base != nil { 769 base.AddMethod(m) 770 } 771 } 772 } 773 774 func (check *Checker) checkFieldUniqueness(base *Named) { 775 if t, _ := base.under().(*Struct); t != nil { 776 var mset objset 777 for i := 0; i < base.NumMethods(); i++ { 778 m := base.Method(i) 779 assert(m.name != "_") 780 assert(mset.insert(m) == nil) 781 } 782 783 // Check that any non-blank field names of base are distinct from its 784 // method names. 785 for _, fld := range t.fields { 786 if fld.name != "_" { 787 if alt := mset.insert(fld); alt != nil { 788 // Struct fields should already be unique, so we should only 789 // encounter an alternate via collision with a method name. 790 _ = alt.(*Func) 791 792 // For historical consistency, we report the primary error on the 793 // method, and the alt decl on the field. 794 check.errorf(alt, DuplicateFieldAndMethod, "field and method with the same name %s", fld.name) 795 check.reportAltDecl(fld) 796 } 797 } 798 } 799 } 800 } 801 802 func (check *Checker) funcDecl(obj *Func, decl *declInfo) { 803 assert(obj.typ == nil) 804 805 // func declarations cannot use iota 806 assert(check.iota == nil) 807 808 sig := new(Signature) 809 obj.typ = sig // guard against cycles 810 811 // Avoid cycle error when referring to method while type-checking the signature. 812 // This avoids a nuisance in the best case (non-parameterized receiver type) and 813 // since the method is not a type, we get an error. If we have a parameterized 814 // receiver type, instantiating the receiver type leads to the instantiation of 815 // its methods, and we don't want a cycle error in that case. 816 // TODO(gri) review if this is correct and/or whether we still need this? 817 saved := obj.color_ 818 obj.color_ = black 819 fdecl := decl.fdecl 820 check.funcType(sig, fdecl.Recv, fdecl.Type) 821 obj.color_ = saved 822 823 if fdecl.Type.TypeParams.NumFields() > 0 && fdecl.Body == nil { 824 check.softErrorf(fdecl.Name, BadDecl, "generic function is missing function body") 825 } 826 827 // function body must be type-checked after global declarations 828 // (functions implemented elsewhere have no body) 829 if !check.conf.IgnoreFuncBodies && fdecl.Body != nil { 830 check.later(func() { 831 check.funcBody(decl, obj.name, sig, fdecl.Body, nil) 832 }).describef(obj, "func %s", obj.name) 833 } 834 } 835 836 func (check *Checker) declStmt(d ast.Decl) { 837 pkg := check.pkg 838 839 check.walkDecl(d, func(d decl) { 840 switch d := d.(type) { 841 case constDecl: 842 top := len(check.delayed) 843 844 // declare all constants 845 lhs := make([]*Const, len(d.spec.Names)) 846 for i, name := range d.spec.Names { 847 obj := NewConst(name.Pos(), pkg, name.Name, nil, constant.MakeInt64(int64(d.iota))) 848 lhs[i] = obj 849 850 var init ast.Expr 851 if i < len(d.init) { 852 init = d.init[i] 853 } 854 855 check.constDecl(obj, d.typ, init, d.inherited) 856 } 857 858 // process function literals in init expressions before scope changes 859 check.processDelayed(top) 860 861 // spec: "The scope of a constant or variable identifier declared 862 // inside a function begins at the end of the ConstSpec or VarSpec 863 // (ShortVarDecl for short variable declarations) and ends at the 864 // end of the innermost containing block." 865 scopePos := d.spec.End() 866 for i, name := range d.spec.Names { 867 check.declare(check.scope, name, lhs[i], scopePos) 868 } 869 870 case varDecl: 871 top := len(check.delayed) 872 873 lhs0 := make([]*Var, len(d.spec.Names)) 874 for i, name := range d.spec.Names { 875 lhs0[i] = NewVar(name.Pos(), pkg, name.Name, nil) 876 } 877 878 // initialize all variables 879 for i, obj := range lhs0 { 880 var lhs []*Var 881 var init ast.Expr 882 switch len(d.spec.Values) { 883 case len(d.spec.Names): 884 // lhs and rhs match 885 init = d.spec.Values[i] 886 case 1: 887 // rhs is expected to be a multi-valued expression 888 lhs = lhs0 889 init = d.spec.Values[0] 890 default: 891 if i < len(d.spec.Values) { 892 init = d.spec.Values[i] 893 } 894 } 895 check.varDecl(obj, lhs, d.spec.Type, init) 896 if len(d.spec.Values) == 1 { 897 // If we have a single lhs variable we are done either way. 898 // If we have a single rhs expression, it must be a multi- 899 // valued expression, in which case handling the first lhs 900 // variable will cause all lhs variables to have a type 901 // assigned, and we are done as well. 902 if debug { 903 for _, obj := range lhs0 { 904 assert(obj.typ != nil) 905 } 906 } 907 break 908 } 909 } 910 911 // process function literals in init expressions before scope changes 912 check.processDelayed(top) 913 914 // declare all variables 915 // (only at this point are the variable scopes (parents) set) 916 scopePos := d.spec.End() // see constant declarations 917 for i, name := range d.spec.Names { 918 // see constant declarations 919 check.declare(check.scope, name, lhs0[i], scopePos) 920 } 921 922 case typeDecl: 923 obj := NewTypeName(d.spec.Name.Pos(), pkg, d.spec.Name.Name, nil) 924 // spec: "The scope of a type identifier declared inside a function 925 // begins at the identifier in the TypeSpec and ends at the end of 926 // the innermost containing block." 927 scopePos := d.spec.Name.Pos() 928 check.declare(check.scope, d.spec.Name, obj, scopePos) 929 // mark and unmark type before calling typeDecl; its type is still nil (see Checker.objDecl) 930 obj.setColor(grey + color(check.push(obj))) 931 check.typeDecl(obj, d.spec, nil) 932 check.pop().setColor(black) 933 default: 934 check.errorf(d.node(), InvalidSyntaxTree, "unknown ast.Decl node %T", d.node()) 935 } 936 }) 937 }