ureader.go (21149B)
1 // Copyright 2021 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 // Derived from go/internal/gcimporter/ureader.go 6 7 package gcimporter 8 9 import ( 10 "fmt" 11 "go/token" 12 "go/types" 13 "sort" 14 "strings" 15 16 "golang.org/x/tools/internal/aliases" 17 "golang.org/x/tools/internal/pkgbits" 18 "golang.org/x/tools/internal/typesinternal" 19 ) 20 21 // A pkgReader holds the shared state for reading a unified IR package 22 // description. 23 type pkgReader struct { 24 pkgbits.PkgDecoder 25 26 fake fakeFileSet 27 28 ctxt *types.Context 29 imports map[string]*types.Package // previously imported packages, indexed by path 30 31 // lazily initialized arrays corresponding to the unified IR 32 // PosBase, Pkg, and Type sections, respectively. 33 posBases []string // position bases (i.e., file names) 34 pkgs []*types.Package 35 typs []types.Type 36 37 // laterFns holds functions that need to be invoked at the end of 38 // import reading. 39 // 40 // TODO(mdempsky): Is it safe to have a single "later" slice or do 41 // we need to have multiple passes? See comments on CL 386002 and 42 // go.dev/issue/52104. 43 laterFns []func() 44 // laterFors is used in case of 'type A B' to ensure that B is processed before A. 45 laterFors map[types.Type]int 46 47 // ifaces holds a list of constructed Interfaces, which need to have 48 // Complete called after importing is done. 49 ifaces []*types.Interface 50 } 51 52 // later adds a function to be invoked at the end of import reading. 53 func (pr *pkgReader) later(fn func()) { 54 pr.laterFns = append(pr.laterFns, fn) 55 } 56 57 // See cmd/compile/internal/noder.derivedInfo. 58 type derivedInfo struct { 59 idx pkgbits.Index 60 } 61 62 // See cmd/compile/internal/noder.typeInfo. 63 type typeInfo struct { 64 idx pkgbits.Index 65 derived bool 66 } 67 68 func UImportData(fset *token.FileSet, imports map[string]*types.Package, data []byte, path string) (_ int, pkg *types.Package, err error) { 69 if !debug { 70 defer func() { 71 if x := recover(); x != nil { 72 err = fmt.Errorf("internal error in importing %q (%v); please report an issue", path, x) 73 } 74 }() 75 } 76 77 s := string(data) 78 input := pkgbits.NewPkgDecoder(path, s) 79 pkg = readUnifiedPackage(fset, nil, imports, input) 80 return 81 } 82 83 // laterFor adds a function to be invoked at the end of import reading, and records the type that function is finishing. 84 func (pr *pkgReader) laterFor(t types.Type, fn func()) { 85 if pr.laterFors == nil { 86 pr.laterFors = make(map[types.Type]int) 87 } 88 pr.laterFors[t] = len(pr.laterFns) 89 pr.laterFns = append(pr.laterFns, fn) 90 } 91 92 // readUnifiedPackage reads a package description from the given 93 // unified IR export data decoder. 94 func readUnifiedPackage(fset *token.FileSet, ctxt *types.Context, imports map[string]*types.Package, input pkgbits.PkgDecoder) *types.Package { 95 pr := pkgReader{ 96 PkgDecoder: input, 97 98 fake: fakeFileSet{ 99 fset: fset, 100 files: make(map[string]*fileInfo), 101 }, 102 103 ctxt: ctxt, 104 imports: imports, 105 106 posBases: make([]string, input.NumElems(pkgbits.RelocPosBase)), 107 pkgs: make([]*types.Package, input.NumElems(pkgbits.RelocPkg)), 108 typs: make([]types.Type, input.NumElems(pkgbits.RelocType)), 109 } 110 defer pr.fake.setLines() 111 112 r := pr.newReader(pkgbits.RelocMeta, pkgbits.PublicRootIdx, pkgbits.SyncPublic) 113 pkg := r.pkg() 114 if r.Version().Has(pkgbits.HasInit) { 115 r.Bool() 116 } 117 118 for i, n := 0, r.Len(); i < n; i++ { 119 // As if r.obj(), but avoiding the Scope.Lookup call, 120 // to avoid eager loading of imports. 121 r.Sync(pkgbits.SyncObject) 122 if r.Version().Has(pkgbits.DerivedFuncInstance) { 123 assert(!r.Bool()) 124 } 125 r.p.objIdx(r.Reloc(pkgbits.RelocObj)) 126 assert(r.Len() == 0) 127 } 128 129 r.Sync(pkgbits.SyncEOF) 130 131 for _, fn := range pr.laterFns { 132 fn() 133 } 134 135 for _, iface := range pr.ifaces { 136 iface.Complete() 137 } 138 139 // Imports() of pkg are all of the transitive packages that were loaded. 140 var imps []*types.Package 141 for _, imp := range pr.pkgs { 142 if imp != nil && imp != pkg { 143 imps = append(imps, imp) 144 } 145 } 146 sort.Sort(byPath(imps)) 147 pkg.SetImports(imps) 148 149 pkg.MarkComplete() 150 return pkg 151 } 152 153 // A reader holds the state for reading a single unified IR element 154 // within a package. 155 type reader struct { 156 pkgbits.Decoder 157 158 p *pkgReader 159 160 dict *readerDict 161 } 162 163 // A readerDict holds the state for type parameters that parameterize 164 // the current unified IR element. 165 type readerDict struct { 166 rtbounds []typeInfo // contains constraint types for each parameter in rtparams 167 rtparams []*types.TypeParam // contains receiver type parameters for an element 168 169 tbounds []typeInfo // contains constraint types for each parameter in tparams 170 tparams []*types.TypeParam // contains type parameters for an element 171 172 // derived is a slice of types derived from tparams, which may be 173 // instantiated while reading the current element. 174 derived []derivedInfo 175 derivedTypes []types.Type // lazily instantiated from derived 176 } 177 178 func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { 179 return &reader{ 180 Decoder: pr.NewDecoder(k, idx, marker), 181 p: pr, 182 } 183 } 184 185 func (pr *pkgReader) tempReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pkgbits.SyncMarker) *reader { 186 return &reader{ 187 Decoder: pr.TempDecoder(k, idx, marker), 188 p: pr, 189 } 190 } 191 192 func (pr *pkgReader) retireReader(r *reader) { 193 pr.RetireDecoder(&r.Decoder) 194 } 195 196 // @@@ Positions 197 198 func (r *reader) pos() token.Pos { 199 r.Sync(pkgbits.SyncPos) 200 if !r.Bool() { 201 return token.NoPos 202 } 203 204 // TODO(mdempsky): Delta encoding. 205 posBase := r.posBase() 206 line := r.Uint() 207 col := r.Uint() 208 return r.p.fake.pos(posBase, int(line), int(col)) 209 } 210 211 func (r *reader) posBase() string { 212 return r.p.posBaseIdx(r.Reloc(pkgbits.RelocPosBase)) 213 } 214 215 func (pr *pkgReader) posBaseIdx(idx pkgbits.Index) string { 216 if b := pr.posBases[idx]; b != "" { 217 return b 218 } 219 220 var filename string 221 { 222 r := pr.tempReader(pkgbits.RelocPosBase, idx, pkgbits.SyncPosBase) 223 224 // Within types2, position bases have a lot more details (e.g., 225 // keeping track of where //line directives appeared exactly). 226 // 227 // For go/types, we just track the file name. 228 229 filename = r.String() 230 231 if r.Bool() { // file base 232 // Was: "b = token.NewTrimmedFileBase(filename, true)" 233 } else { // line base 234 pos := r.pos() 235 line := r.Uint() 236 col := r.Uint() 237 238 // Was: "b = token.NewLineBase(pos, filename, true, line, col)" 239 _, _, _ = pos, line, col 240 } 241 pr.retireReader(r) 242 } 243 b := filename 244 pr.posBases[idx] = b 245 return b 246 } 247 248 // @@@ Packages 249 250 func (r *reader) pkg() *types.Package { 251 r.Sync(pkgbits.SyncPkg) 252 return r.p.pkgIdx(r.Reloc(pkgbits.RelocPkg)) 253 } 254 255 func (pr *pkgReader) pkgIdx(idx pkgbits.Index) *types.Package { 256 // TODO(mdempsky): Consider using some non-nil pointer to indicate 257 // the universe scope, so we don't need to keep re-reading it. 258 if pkg := pr.pkgs[idx]; pkg != nil { 259 return pkg 260 } 261 262 pkg := pr.newReader(pkgbits.RelocPkg, idx, pkgbits.SyncPkgDef).doPkg() 263 pr.pkgs[idx] = pkg 264 return pkg 265 } 266 267 func (r *reader) doPkg() *types.Package { 268 path := r.String() 269 switch path { 270 // cmd/compile emits path="main" for main packages because 271 // that's the linker symbol prefix it used; but we need 272 // the package's path as it would be reported by go list, 273 // hence "main" below. 274 // See test at go/packages.TestMainPackagePathInModeTypes. 275 case "", "main": 276 path = r.p.PkgPath() 277 case "builtin": 278 return nil // universe 279 case "unsafe": 280 return types.Unsafe 281 } 282 283 if pkg := r.p.imports[path]; pkg != nil { 284 return pkg 285 } 286 287 name := r.String() 288 289 pkg := types.NewPackage(path, name) 290 r.p.imports[path] = pkg 291 292 return pkg 293 } 294 295 // @@@ Types 296 297 func (r *reader) typ() types.Type { 298 return r.p.typIdx(r.typInfo(), r.dict) 299 } 300 301 func (r *reader) typInfo() typeInfo { 302 r.Sync(pkgbits.SyncType) 303 if r.Bool() { 304 return typeInfo{idx: pkgbits.Index(r.Len()), derived: true} 305 } 306 return typeInfo{idx: r.Reloc(pkgbits.RelocType), derived: false} 307 } 308 309 func (pr *pkgReader) typIdx(info typeInfo, dict *readerDict) types.Type { 310 idx := info.idx 311 var where *types.Type 312 if info.derived { 313 where = &dict.derivedTypes[idx] 314 idx = dict.derived[idx].idx 315 } else { 316 where = &pr.typs[idx] 317 } 318 319 if typ := *where; typ != nil { 320 return typ 321 } 322 323 var typ types.Type 324 { 325 r := pr.tempReader(pkgbits.RelocType, idx, pkgbits.SyncTypeIdx) 326 r.dict = dict 327 328 typ = r.doTyp() 329 assert(typ != nil) 330 pr.retireReader(r) 331 } 332 // See comment in pkgReader.typIdx explaining how this happens. 333 if prev := *where; prev != nil { 334 return prev 335 } 336 337 *where = typ 338 return typ 339 } 340 341 func (r *reader) doTyp() (res types.Type) { 342 switch tag := pkgbits.CodeType(r.Code(pkgbits.SyncType)); tag { 343 default: 344 errorf("unhandled type tag: %v", tag) 345 panic("unreachable") 346 347 case pkgbits.TypeBasic: 348 return types.Typ[r.Len()] 349 350 case pkgbits.TypeNamed: 351 obj, targs := r.obj() 352 name := obj.(*types.TypeName) 353 if len(targs) != 0 { 354 t, _ := types.Instantiate(r.p.ctxt, name.Type(), targs, false) 355 return t 356 } 357 return name.Type() 358 359 case pkgbits.TypeTypeParam: 360 n := r.Len() 361 if n < len(r.dict.rtbounds) { 362 return r.dict.rtparams[n] 363 } 364 return r.dict.tparams[n-len(r.dict.rtbounds)] 365 366 case pkgbits.TypeArray: 367 len := int64(r.Uint64()) 368 return types.NewArray(r.typ(), len) 369 case pkgbits.TypeChan: 370 dir := types.ChanDir(r.Len()) 371 return types.NewChan(dir, r.typ()) 372 case pkgbits.TypeMap: 373 return types.NewMap(r.typ(), r.typ()) 374 case pkgbits.TypePointer: 375 return types.NewPointer(r.typ()) 376 case pkgbits.TypeSignature: 377 return r.signature(nil, nil, nil) 378 case pkgbits.TypeSlice: 379 return types.NewSlice(r.typ()) 380 case pkgbits.TypeStruct: 381 return r.structType() 382 case pkgbits.TypeInterface: 383 return r.interfaceType() 384 case pkgbits.TypeUnion: 385 return r.unionType() 386 } 387 } 388 389 func (r *reader) structType() *types.Struct { 390 fields := make([]*types.Var, r.Len()) 391 var tags []string 392 for i := range fields { 393 pos := r.pos() 394 pkg, name := r.selector() 395 ftyp := r.typ() 396 tag := r.String() 397 embedded := r.Bool() 398 399 fields[i] = types.NewField(pos, pkg, name, ftyp, embedded) 400 if tag != "" { 401 for len(tags) < i { 402 tags = append(tags, "") 403 } 404 tags = append(tags, tag) 405 } 406 } 407 return types.NewStruct(fields, tags) 408 } 409 410 func (r *reader) unionType() *types.Union { 411 terms := make([]*types.Term, r.Len()) 412 for i := range terms { 413 terms[i] = types.NewTerm(r.Bool(), r.typ()) 414 } 415 return types.NewUnion(terms) 416 } 417 418 func (r *reader) interfaceType() *types.Interface { 419 methods := make([]*types.Func, r.Len()) 420 embeddeds := make([]types.Type, r.Len()) 421 implicit := len(methods) == 0 && len(embeddeds) == 1 && r.Bool() 422 423 for i := range methods { 424 pos := r.pos() 425 pkg, name := r.selector() 426 mtyp := r.signature(nil, nil, nil) 427 methods[i] = types.NewFunc(pos, pkg, name, mtyp) 428 } 429 430 for i := range embeddeds { 431 embeddeds[i] = r.typ() 432 } 433 434 iface := types.NewInterfaceType(methods, embeddeds) 435 if implicit { 436 iface.MarkImplicit() 437 } 438 439 // We need to call iface.Complete(), but if there are any embedded 440 // defined types, then we may not have set their underlying 441 // interface type yet. So we need to defer calling Complete until 442 // after we've called SetUnderlying everywhere. 443 // 444 // TODO(mdempsky): After CL 424876 lands, it should be safe to call 445 // iface.Complete() immediately. 446 r.p.ifaces = append(r.p.ifaces, iface) 447 448 return iface 449 } 450 451 func (r *reader) signature(recv *types.Var, rtparams, tparams []*types.TypeParam) *types.Signature { 452 r.Sync(pkgbits.SyncSignature) 453 454 params := r.params() 455 results := r.params() 456 variadic := r.Bool() 457 458 return types.NewSignatureType(recv, rtparams, tparams, params, results, variadic) 459 } 460 461 func (r *reader) params() *types.Tuple { 462 r.Sync(pkgbits.SyncParams) 463 464 params := make([]*types.Var, r.Len()) 465 for i := range params { 466 params[i] = r.param() 467 } 468 469 return types.NewTuple(params...) 470 } 471 472 func (r *reader) param() *types.Var { 473 r.Sync(pkgbits.SyncParam) 474 475 pos := r.pos() 476 pkg, name := r.localIdent() 477 typ := r.typ() 478 479 return types.NewParam(pos, pkg, name, typ) 480 } 481 482 // @@@ Objects 483 484 func (r *reader) obj() (types.Object, []types.Type) { 485 r.Sync(pkgbits.SyncObject) 486 487 if r.Version().Has(pkgbits.DerivedFuncInstance) { 488 assert(!r.Bool()) 489 } 490 491 pkg, name := r.p.objIdx(r.Reloc(pkgbits.RelocObj)) 492 obj := pkgScope(pkg).Lookup(name) 493 494 targs := make([]types.Type, r.Len()) 495 for i := range targs { 496 targs[i] = r.typ() 497 } 498 499 return obj, targs 500 } 501 502 func (pr *pkgReader) objIdx(idx pkgbits.Index) (*types.Package, string) { 503 504 var objPkg *types.Package 505 var objName string 506 var tag pkgbits.CodeObj 507 { 508 rname := pr.tempReader(pkgbits.RelocName, idx, pkgbits.SyncObject1) 509 510 objPkg, objName = rname.qualifiedIdent() 511 assert(objName != "") 512 513 tag = pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) 514 pr.retireReader(rname) 515 } 516 517 if tag == pkgbits.ObjStub { 518 assert(objPkg == nil || objPkg == types.Unsafe) 519 return objPkg, objName 520 } 521 522 // Ignore local types promoted to global scope (#55110). 523 if _, suffix := splitVargenSuffix(objName); suffix != "" { 524 return objPkg, objName 525 } 526 527 // TODO(mark): This, like the above splitVargenSuffix, is not ideal. 528 // Ignore generic methods promoted to global scope. 529 if strings.Contains(objName, ".") { 530 return objPkg, objName 531 } 532 533 if objPkg.Scope().Lookup(objName) == nil { 534 dict := pr.objDictIdx(idx) 535 536 r := pr.newReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) 537 r.dict = dict 538 539 declare := func(obj types.Object) { 540 objPkg.Scope().Insert(obj) 541 } 542 543 switch tag { 544 default: 545 panic("weird") 546 547 case pkgbits.ObjAlias: 548 pos := r.pos() 549 var tparams []*types.TypeParam 550 if r.Version().Has(pkgbits.AliasTypeParamNames) { 551 tparams = r.typeParamNames(false) 552 } 553 typ := r.typ() 554 declare(aliases.New(pos, objPkg, objName, typ, tparams)) 555 556 case pkgbits.ObjConst: 557 pos := r.pos() 558 typ := r.typ() 559 val := r.Value() 560 declare(types.NewConst(pos, objPkg, objName, typ, val)) 561 562 case pkgbits.ObjFunc: 563 pos := r.pos() 564 if r.Version().Has(pkgbits.GenericMethods) { 565 assert(!r.Bool()) // generic methods are read in their defining type 566 } 567 tparams := r.typeParamNames(false) 568 sig := r.signature(nil, nil, tparams) 569 declare(types.NewFunc(pos, objPkg, objName, sig)) 570 571 case pkgbits.ObjType: 572 pos := r.pos() 573 574 obj := types.NewTypeName(pos, objPkg, objName, nil) 575 named := types.NewNamed(obj, nil, nil) 576 declare(obj) 577 578 named.SetTypeParams(r.typeParamNames(false)) 579 580 setUnderlying := func(underlying types.Type) { 581 // If the underlying type is an interface, we need to 582 // duplicate its methods so we can replace the receiver 583 // parameter's type (#49906). 584 if iface, ok := types.Unalias(underlying).(*types.Interface); ok && iface.NumExplicitMethods() != 0 { 585 methods := make([]*types.Func, iface.NumExplicitMethods()) 586 for i := range methods { 587 fn := iface.ExplicitMethod(i) 588 sig := fn.Type().(*types.Signature) 589 590 recv := types.NewVar(fn.Pos(), fn.Pkg(), "", named) 591 typesinternal.SetVarKind(recv, typesinternal.RecvVar) 592 methods[i] = types.NewFunc(fn.Pos(), fn.Pkg(), fn.Name(), types.NewSignatureType(recv, nil, nil, sig.Params(), sig.Results(), sig.Variadic())) 593 } 594 595 embeds := make([]types.Type, iface.NumEmbeddeds()) 596 for i := range embeds { 597 embeds[i] = iface.EmbeddedType(i) 598 } 599 600 newIface := types.NewInterfaceType(methods, embeds) 601 r.p.ifaces = append(r.p.ifaces, newIface) 602 underlying = newIface 603 } 604 605 named.SetUnderlying(underlying) 606 } 607 608 // Since go.dev/cl/455279, we can assume rhs.Underlying() will 609 // always be non-nil. However, to temporarily support users of 610 // older snapshot releases, we continue to fallback to the old 611 // behavior for now. 612 // 613 // TODO(mdempsky): Remove fallback code and simplify after 614 // allowing time for snapshot users to upgrade. 615 rhs := r.typ() 616 if underlying := rhs.Underlying(); underlying != nil { 617 setUnderlying(underlying) 618 } else { 619 pk := r.p 620 pk.laterFor(named, func() { 621 // First be sure that the rhs is initialized, if it needs to be initialized. 622 delete(pk.laterFors, named) // prevent cycles 623 if i, ok := pk.laterFors[rhs]; ok { 624 f := pk.laterFns[i] 625 pk.laterFns[i] = func() {} // function is running now, so replace it with a no-op 626 f() // initialize RHS 627 } 628 setUnderlying(rhs.Underlying()) 629 }) 630 } 631 632 for i, n := 0, r.Len(); i < n; i++ { 633 named.AddMethod(r.method()) 634 } 635 636 if r.Version().Has(pkgbits.GenericMethods) { 637 for range r.Len() { 638 // Careful: objIdx is used to read in package-scoped declarations, which 639 // methods are not. Instead, decode it here. This makes it easier to 640 // associate it with the type and avoids the main objIdx loop. 641 idx := r.Reloc(pkgbits.RelocObj) 642 643 r := pr.tempReader(pkgbits.RelocObj, idx, pkgbits.SyncObject1) 644 r.dict = pr.objDictIdx(idx) 645 646 pos := r.pos() 647 assert(r.Bool()) // generic method 648 pkg, name := r.selector() 649 rtparams := r.typeParamNames(true) 650 recv := r.param() 651 tparams := r.typeParamNames(false) 652 sig := r.signature(recv, rtparams, tparams) 653 654 pr.retireReader(r) 655 named.AddMethod(types.NewFunc(pos, pkg, name, sig)) 656 } 657 } 658 659 case pkgbits.ObjVar: 660 pos := r.pos() 661 typ := r.typ() 662 v := types.NewVar(pos, objPkg, objName, typ) 663 typesinternal.SetVarKind(v, typesinternal.PackageVar) 664 declare(v) 665 } 666 } 667 668 return objPkg, objName 669 } 670 671 func (pr *pkgReader) objDictIdx(idx pkgbits.Index) *readerDict { 672 673 var dict readerDict 674 675 { 676 r := pr.tempReader(pkgbits.RelocObjDict, idx, pkgbits.SyncObject1) 677 if implicits := r.Len(); implicits != 0 { 678 errorf("unexpected object with %v implicit type parameter(s)", implicits) 679 } 680 681 nreceivers := 0 682 if r.Version().Has(pkgbits.GenericMethods) { 683 nreceivers = r.Len() 684 } 685 nexplicits := r.Len() 686 687 dict.rtbounds = make([]typeInfo, nreceivers) 688 for i := range dict.rtbounds { 689 dict.rtbounds[i] = r.typInfo() 690 } 691 692 dict.tbounds = make([]typeInfo, nexplicits) 693 for i := range dict.tbounds { 694 dict.tbounds[i] = r.typInfo() 695 } 696 697 dict.derived = make([]derivedInfo, r.Len()) 698 dict.derivedTypes = make([]types.Type, len(dict.derived)) 699 for i := range dict.derived { 700 dict.derived[i] = derivedInfo{idx: r.Reloc(pkgbits.RelocType)} 701 if r.Version().Has(pkgbits.DerivedInfoNeeded) { 702 assert(!r.Bool()) 703 } 704 } 705 706 pr.retireReader(r) 707 } 708 // function references follow, but reader doesn't need those 709 710 return &dict 711 } 712 713 func (r *reader) typeParamNames(isGenMeth bool) []*types.TypeParam { 714 r.Sync(pkgbits.SyncTypeParamNames) 715 716 // Note: This code assumes there are no implicit type parameters. 717 // This is fine since it only reads exported declarations, which 718 // never have implicits. 719 720 var in []typeInfo 721 var out *[]*types.TypeParam 722 if isGenMeth { 723 in = r.dict.rtbounds 724 out = &r.dict.rtparams 725 } else { 726 in = r.dict.tbounds 727 out = &r.dict.tparams 728 } 729 730 if len(in) == 0 { 731 return nil 732 } 733 734 // Careful: Type parameter lists may have cycles. To allow for this, 735 // we construct the type parameter list in two passes: first we 736 // create all the TypeNames and TypeParams, then we construct and 737 // set the bound type. 738 739 // We have to save tparams outside of the closure, because typeParamNames 740 // can be called multiple times with the same dictionary instance. 741 tparams := make([]*types.TypeParam, len(in)) 742 *out = tparams 743 744 for i := range in { 745 pos := r.pos() 746 pkg, name := r.localIdent() 747 748 tname := types.NewTypeName(pos, pkg, name, nil) 749 tparams[i] = types.NewTypeParam(tname, nil) 750 } 751 752 // The reader dictionary will continue mutating before we have time 753 // to call delayed functions; make a local copy of the constraints. 754 types := make([]types.Type, len(in)) 755 for i, info := range in { 756 types[i] = r.p.typIdx(info, r.dict) 757 } 758 759 // This needs to happen later to make sure SetUnderlying has been called. 760 r.p.later(func() { 761 for i, typ := range types { 762 tparams[i].SetConstraint(typ) 763 } 764 }) 765 766 return tparams 767 } 768 769 func (r *reader) method() *types.Func { 770 r.Sync(pkgbits.SyncMethod) 771 pos := r.pos() 772 pkg, name := r.selector() 773 774 rparams := r.typeParamNames(false) 775 sig := r.signature(r.param(), rparams, nil) 776 777 _ = r.pos() // TODO(mdempsky): Remove; this is a hacker for linker.go. 778 return types.NewFunc(pos, pkg, name, sig) 779 } 780 781 func (r *reader) qualifiedIdent() (*types.Package, string) { return r.ident(pkgbits.SyncSym) } 782 func (r *reader) localIdent() (*types.Package, string) { return r.ident(pkgbits.SyncLocalIdent) } 783 func (r *reader) selector() (*types.Package, string) { return r.ident(pkgbits.SyncSelector) } 784 785 func (r *reader) ident(marker pkgbits.SyncMarker) (*types.Package, string) { 786 r.Sync(marker) 787 return r.pkg(), r.String() 788 } 789 790 // pkgScope returns pkg.Scope(). 791 // If pkg is nil, it returns types.Universe instead. 792 // 793 // TODO(mdempsky): Remove after x/tools can depend on Go 1.19. 794 func pkgScope(pkg *types.Package) *types.Scope { 795 if pkg != nil { 796 return pkg.Scope() 797 } 798 return types.Universe 799 } 800 801 // See cmd/compile/internal/types.SplitVargenSuffix. 802 func splitVargenSuffix(name string) (base, suffix string) { 803 i := len(name) 804 for i > 0 && name[i-1] >= '0' && name[i-1] <= '9' { 805 i-- 806 } 807 const dot = "ยท" 808 if i >= len(dot) && name[i-len(dot):i] == dot { 809 i -= len(dot) 810 return name[:i], name[i:] 811 } 812 return name, "" 813 }