mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 10:47:27 +08:00 
			
		
		
		
	Updates for go1.18beta1 (#2831)
* go.mod: update golang.org/x/tools to v0.1.8 Fixes TestGeneratedDoc on go1.18 * TeamCity: bump test matrix Add 1.18 to test matrix. Remove 1.15 from test matrix and from support range. * proc,tests: update for regabi on arm64 and 386 Make sure that stacktrace registers always contain the PC register of the current frame, even though the debug_frame rules might not specify it on architectures that use a link register. The PC register is needed to look up loclist entries for variable evaluation. * goversion: bump maximum supported Go version to 1.18 * proc: disable asyncpreempt on linux/arm64 Asyncpreempt on linux/arm64 can sometimes restart a sequence of instructions which will make breakpoint appear to be hit twice in some cases.
This commit is contained in:
		 Alessandro Arzilli
					Alessandro Arzilli
				
			
				
					committed by
					
						 GitHub
						GitHub
					
				
			
			
				
	
			
			
			 GitHub
						GitHub
					
				
			
						parent
						
							07bcf0cb13
						
					
				
				
					commit
					4a94b3eff2
				
			
							
								
								
									
										12
									
								
								.teamcity/settings.kts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.teamcity/settings.kts
									
									
									
									
										vendored
									
									
								
							| @ -35,23 +35,23 @@ To debug in IntelliJ Idea, open the 'Maven Projects' tool window (View | ||||
| version = "2020.2" | ||||
|  | ||||
| val targets = arrayOf( | ||||
|         "linux/amd64/1.15", | ||||
|         "linux/amd64/1.16", | ||||
|         "linux/amd64/1.17", | ||||
|         "linux/amd64/1.18", | ||||
|         "linux/amd64/tip", | ||||
|  | ||||
|         "linux/386/1.17", | ||||
|         "linux/386/1.18", | ||||
|  | ||||
|         "linux/arm64/1.17", | ||||
|         "linux/arm64/1.18", | ||||
|         "linux/arm64/tip", | ||||
|  | ||||
|         "windows/amd64/1.17", | ||||
|         "windows/amd64/1.18", | ||||
|         "windows/amd64/tip", | ||||
|  | ||||
|         "mac/amd64/1.17", | ||||
|         "mac/amd64/1.18", | ||||
|         "mac/amd64/tip", | ||||
|  | ||||
|         "mac/arm64/1.17", | ||||
|         "mac/arm64/1.18", | ||||
|         "mac/arm64/tip" | ||||
| ) | ||||
|  | ||||
|  | ||||
| @ -21,10 +21,6 @@ function getgo { | ||||
| } | ||||
|  | ||||
| if [ "$version" = "gotip" ]; then | ||||
| 	# TODO: remove this | ||||
| 	if [ "$arch" != "amd64" ]; then | ||||
| 		exit 0 | ||||
| 	fi | ||||
| 	echo Building Go from tip | ||||
| 	getgo $(curl https://go.dev/VERSION?m=text) | ||||
| 	export GOROOT_BOOTSTRAP=$GOROOT | ||||
|  | ||||
| @ -8,10 +8,6 @@ ARCH=$2 | ||||
| TMPDIR=$3 | ||||
|  | ||||
| if [ "$GOVERSION" = "gotip" ]; then | ||||
|     # TODO: remove this | ||||
|     if [ "$arch" != "amd64" ]; then | ||||
|         exit 0 | ||||
|     fi | ||||
|     bootstrapver=$(curl https://go.dev/VERSION?m=text) | ||||
|     cd $TMPDIR | ||||
|     curl -sSL "https://storage.googleapis.com/golang/$bootstrapver.darwin-$ARCH.tar.gz" | tar -xz | ||||
|  | ||||
| @ -34,7 +34,7 @@ function GetGo($version) { | ||||
| } | ||||
|  | ||||
| if ($version -eq "gotip") { | ||||
|     Exit 0 | ||||
|     #Exit 0 | ||||
|     $latest = Invoke-WebRequest -Uri https://golang.org/VERSION?m=text -UseBasicParsing | Select-Object -ExpandProperty Content | ||||
|     GetGo $latest | ||||
|     $env:GOROOT_BOOTSTRAP = $env:GOROOT | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @ -18,6 +18,6 @@ require ( | ||||
| 	go.starlark.net v0.0.0-20200821142938-949cc6f4b097 | ||||
| 	golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 | ||||
| 	golang.org/x/sys v0.0.0-20211019181941-9d821ace8654 | ||||
| 	golang.org/x/tools v0.1.8-0.20211028023602-8de2a7fd1736 | ||||
| 	golang.org/x/tools v0.1.8 | ||||
| 	gopkg.in/yaml.v2 v2.4.0 | ||||
| ) | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -309,6 +309,8 @@ golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtn | ||||
| golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.1.8-0.20211028023602-8de2a7fd1736 h1:cw6nUxdoEN5iEIWYD8aAsTZ8iYjLVNiHAb7xz/80WO4= | ||||
| golang.org/x/tools v0.1.8-0.20211028023602-8de2a7fd1736/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= | ||||
| golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w= | ||||
| golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
|  | ||||
| @ -8,9 +8,9 @@ import ( | ||||
|  | ||||
| var ( | ||||
| 	MinSupportedVersionOfGoMajor = 1 | ||||
| 	MinSupportedVersionOfGoMinor = 15 | ||||
| 	MinSupportedVersionOfGoMinor = 16 | ||||
| 	MaxSupportedVersionOfGoMajor = 1 | ||||
| 	MaxSupportedVersionOfGoMinor = 17 | ||||
| 	MaxSupportedVersionOfGoMinor = 18 | ||||
| 	goTooOldErr                  = fmt.Sprintf("Go version %%s is too old for this version of Delve (minimum supported version %d.%d, suppress this error with --check-go-version=false)", MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor) | ||||
| 	goTooOldWarn                 = fmt.Sprintf("WARNING: undefined behavior - Go version %%s is too old for this version of Delve (minimum supported version %d.%d)", MinSupportedVersionOfGoMajor, MinSupportedVersionOfGoMinor) | ||||
| 	dlvTooOldErr                 = fmt.Sprintf("Version of Delve is too old for Go version %%s (maximum supported version %d.%d, suppress this error with --check-go-version=false)", MaxSupportedVersionOfGoMajor, MaxSupportedVersionOfGoMinor) | ||||
|  | ||||
| @ -266,11 +266,23 @@ func (dbp *nativeProcess) initialize(path string, debugInfoDirs []string) (*proc | ||||
| 		stopReason = proc.StopAttached | ||||
| 	} | ||||
| 	tgt, err := proc.NewTarget(dbp, dbp.pid, dbp.memthread, proc.NewTargetConfig{ | ||||
| 		Path:                path, | ||||
| 		DebugInfoDirs:       debugInfoDirs, | ||||
| 		DisableAsyncPreempt: runtime.GOOS == "windows" || runtime.GOOS == "freebsd", | ||||
| 		StopReason:          stopReason, | ||||
| 		CanDump:             runtime.GOOS == "linux"}) | ||||
| 		Path:          path, | ||||
| 		DebugInfoDirs: debugInfoDirs, | ||||
|  | ||||
| 		// We disable asyncpreempt for the following reasons: | ||||
| 		//  - on Windows asyncpreempt is incompatible with debuggers, see: | ||||
| 		//    https://github.com/golang/go/issues/36494 | ||||
| 		//  - freebsd's backend is generally broken and asyncpreempt makes it even more so, see: | ||||
| 		//    https://github.com/go-delve/delve/issues/1754 | ||||
| 		//  - on linux/arm64 asyncpreempt can sometimes restart a sequence of | ||||
| 		//    instructions, if the sequence happens to contain a breakpoint it will | ||||
| 		//    look like the breakpoint was hit twice when it was "logically" only | ||||
| 		//    executed once. | ||||
| 		//    See: https://go-review.googlesource.com/c/go/+/208126 | ||||
| 		DisableAsyncPreempt: runtime.GOOS == "windows" || runtime.GOOS == "freebsd" || (runtime.GOOS == "linux" && runtime.GOARCH == "arm64"), | ||||
|  | ||||
| 		StopReason: stopReason, | ||||
| 		CanDump:    runtime.GOOS == "linux"}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| @ -1335,6 +1335,10 @@ func TestFrameEvaluation(t *testing.T) { | ||||
| 		g, err := proc.GetG(p.CurrentThread()) | ||||
| 		assertNoError(err, t, "GetG()") | ||||
|  | ||||
| 		frames, err := g.Stacktrace(40, 0) | ||||
| 		t.Logf("Goroutine %d %#v", g.ID, g.Thread) | ||||
| 		logStacktrace(t, p, frames) | ||||
|  | ||||
| 		for i := 0; i <= 3; i++ { | ||||
| 			scope, err := proc.ConvertEvalScope(p, g.ID, i+1, 0) | ||||
| 			assertNoError(err, t, fmt.Sprintf("ConvertEvalScope() on frame %d", i+1)) | ||||
|  | ||||
| @ -276,6 +276,9 @@ func (it *stackIterator) newStackframe(ret, retaddr uint64) Stackframe { | ||||
| 		it.regs.FrameBase = it.frameBase(fn) | ||||
| 	} | ||||
| 	r := Stackframe{Current: Location{PC: it.pc, File: f, Line: l, Fn: fn}, Regs: it.regs, Ret: ret, addrret: retaddr, stackHi: it.stackhi, SystemStack: it.systemstack, lastpc: it.pc} | ||||
| 	if r.Regs.Reg(it.regs.PCRegNum) == nil { | ||||
| 		r.Regs.AddReg(it.regs.PCRegNum, op.DwarfRegisterFromUint64(it.pc)) | ||||
| 	} | ||||
| 	r.Call = r.Current | ||||
| 	if !it.top && r.Current.Fn != nil && it.pc != r.Current.Fn.Entry { | ||||
| 		// if the return address is the entry point of the function that | ||||
|  | ||||
| @ -383,11 +383,11 @@ func MustHaveCgo(t *testing.T) { | ||||
| func RegabiSupported() bool { | ||||
| 	// Tracks regabiSupported variable in ParseGOEXPERIMENT internal/buildcfg/exp.go | ||||
| 	switch { | ||||
| 	case !goversion.VersionAfterOrEqual(runtime.Version(), 1, 17): // < 1.17 | ||||
| 		return false | ||||
| 	case goversion.VersionAfterOrEqual(runtime.Version(), 1, 18): | ||||
| 		return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "ppc64" | ||||
| 	case goversion.VersionAfterOrEqual(runtime.Version(), 1, 17): | ||||
| 		return runtime.GOARCH == "amd64" && (runtime.GOOS == "android" || runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows") | ||||
| 	default: // >= 1.18 | ||||
| 		return runtime.GOARCH == "amd64" || runtime.GOARCH == "arm64" | ||||
| 	default: | ||||
| 		return false | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -2387,6 +2387,11 @@ func TestGlobalScopeAndVariables(t *testing.T) { | ||||
| 			[]onBreakpoint{{ | ||||
| 				// Stop at line 36 | ||||
| 				execute: func() { | ||||
| 					if runtime.GOARCH == "386" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 18) { | ||||
| 						client.StepInRequest(1) | ||||
| 						client.ExpectStepInResponse(t) | ||||
| 						client.ExpectStoppedEvent(t) | ||||
| 					} | ||||
| 					client.StackTraceRequest(1, 0, 20) | ||||
| 					stack := client.ExpectStackTraceResponse(t) | ||||
| 					checkStackFramesExact(t, stack, "main.main", 36, 1000, 3, 3) | ||||
| @ -2454,6 +2459,12 @@ func TestRegistersScopeAndVariables(t *testing.T) { | ||||
| 			[]onBreakpoint{{ | ||||
| 				// Stop at line 36 | ||||
| 				execute: func() { | ||||
| 					if runtime.GOARCH == "386" && goversion.VersionAfterOrEqual(runtime.Version(), 1, 18) { | ||||
| 						client.StepInRequest(1) | ||||
| 						client.ExpectStepInResponse(t) | ||||
| 						client.ExpectStoppedEvent(t) | ||||
| 					} | ||||
|  | ||||
| 					client.StackTraceRequest(1, 0, 20) | ||||
| 					stack := client.ExpectStackTraceResponse(t) | ||||
| 					checkStackFramesExact(t, stack, "main.main", 36, 1000, 3, 3) | ||||
|  | ||||
							
								
								
									
										22
									
								
								vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/golang.org/x/tools/go/internal/gcimporter/iimport.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -331,7 +331,7 @@ func (p *iimporter) pkgAt(off uint64) *types.Package { | ||||
| } | ||||
|  | ||||
| func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { | ||||
| 	if t, ok := p.typCache[off]; ok && (base == nil || !isInterface(t)) { | ||||
| 	if t, ok := p.typCache[off]; ok && canReuse(base, t) { | ||||
| 		return t | ||||
| 	} | ||||
|  | ||||
| @ -343,12 +343,30 @@ func (p *iimporter) typAt(off uint64, base *types.Named) types.Type { | ||||
| 	r.declReader.Reset(p.declData[off-predeclReserved:]) | ||||
| 	t := r.doType(base) | ||||
|  | ||||
| 	if base == nil || !isInterface(t) { | ||||
| 	if canReuse(base, t) { | ||||
| 		p.typCache[off] = t | ||||
| 	} | ||||
| 	return t | ||||
| } | ||||
|  | ||||
| // canReuse reports whether the type rhs on the RHS of the declaration for def | ||||
| // may be re-used. | ||||
| // | ||||
| // Specifically, if def is non-nil and rhs is an interface type with methods, it | ||||
| // may not be re-used because we have a convention of setting the receiver type | ||||
| // for interface methods to def. | ||||
| func canReuse(def *types.Named, rhs types.Type) bool { | ||||
| 	if def == nil { | ||||
| 		return true | ||||
| 	} | ||||
| 	iface, _ := rhs.(*types.Interface) | ||||
| 	if iface == nil { | ||||
| 		return true | ||||
| 	} | ||||
| 	// Don't use iface.Empty() here as iface may not be complete. | ||||
| 	return iface.NumEmbeddeds() == 0 && iface.NumExplicitMethods() == 0 | ||||
| } | ||||
|  | ||||
| type importReader struct { | ||||
| 	p          *iimporter | ||||
| 	declReader bytes.Reader | ||||
|  | ||||
							
								
								
									
										3
									
								
								vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/golang.org/x/tools/go/internal/gcimporter/support_go118.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -16,5 +16,8 @@ func additionalPredeclared() []types.Type { | ||||
| 	return []types.Type{ | ||||
| 		// comparable | ||||
| 		types.Universe.Lookup("comparable").Type(), | ||||
|  | ||||
| 		// any | ||||
| 		types.Universe.Lookup("any").Type(), | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										7
									
								
								vendor/golang.org/x/tools/internal/typeparams/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/golang.org/x/tools/internal/typeparams/common.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -13,6 +13,7 @@ package typeparams | ||||
| import ( | ||||
| 	"go/ast" | ||||
| 	"go/token" | ||||
| 	"go/types" | ||||
| ) | ||||
|  | ||||
| // A IndexExprData holds data from both ast.IndexExpr and the new | ||||
| @ -23,3 +24,9 @@ type IndexExprData struct { | ||||
| 	Indices []ast.Expr // index expressions | ||||
| 	Rbrack  token.Pos  // position of "]" | ||||
| } | ||||
|  | ||||
| // IsTypeParam reports whether t is a type parameter. | ||||
| func IsTypeParam(t types.Type) bool { | ||||
| 	_, ok := t.(*TypeParam) | ||||
| 	return ok | ||||
| } | ||||
|  | ||||
							
								
								
									
										164
									
								
								vendor/golang.org/x/tools/internal/typeparams/normalize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										164
									
								
								vendor/golang.org/x/tools/internal/typeparams/normalize.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -16,92 +16,96 @@ import ( | ||||
|  | ||||
| const debug = false | ||||
|  | ||||
| // NormalizeInterface returns the normal form of the interface iface, or nil if iface | ||||
| // has an empty type set (i.e. there are no types that satisfy iface). If the | ||||
| // resulting interface is non-nil, it will be identical to iface. | ||||
| var ErrEmptyTypeSet = errors.New("empty type set") | ||||
|  | ||||
| // StructuralTerms returns a slice of terms representing the normalized | ||||
| // structural type restrictions of a type parameter, if any. | ||||
| // | ||||
| // An error is returned if the interface type is invalid, or too complicated to | ||||
| // reasonably normalize (for example, contains unions with more than a hundred | ||||
| // terms). | ||||
| // Structural type restrictions of a type parameter are created via | ||||
| // non-interface types embedded in its constraint interface (directly, or via a | ||||
| // chain of interface embeddings). For example, in the declaration | ||||
| //  type T[P interface{~int; m()}] int | ||||
| // the structural restriction of the type parameter P is ~int. | ||||
| // | ||||
| // An interface is in normal form if and only if: | ||||
| //   - it has 0 or 1 embedded types. | ||||
| //   - its embedded type is either a types.Union or has a concrete | ||||
| //     (non-interface) underlying type | ||||
| //   - if the embedded type is a union, each term of the union has a concrete | ||||
| //     underlying type, and no terms may be removed without changing the type set | ||||
| //     of the interface | ||||
| func NormalizeInterface(iface *types.Interface) (*types.Interface, error) { | ||||
| 	var methods []*types.Func | ||||
| 	for i := 0; i < iface.NumMethods(); i++ { | ||||
| 		methods = append(methods, iface.Method(i)) | ||||
| // With interface embedding and unions, the specification of structural type | ||||
| // restrictions may be arbitrarily complex. For example, consider the | ||||
| // following: | ||||
| // | ||||
| //  type A interface{ ~string|~[]byte } | ||||
| // | ||||
| //  type B interface{ int|string } | ||||
| // | ||||
| //  type C interface { ~string|~int } | ||||
| // | ||||
| //  type T[P interface{ A|B; C }] int | ||||
| // | ||||
| // In this example, the structural type restriction of P is ~string|int: A|B | ||||
| // expands to ~string|~[]byte|int|string, which reduces to ~string|~[]byte|int, | ||||
| // which when intersected with C (~string|~int) yields ~string|int. | ||||
| // | ||||
| // StructuralTerms computes these expansions and reductions, producing a | ||||
| // "normalized" form of the embeddings. A structural restriction is normalized | ||||
| // if it is a single union containing no interface terms, and is minimal in the | ||||
| // sense that removing any term changes the set of types satisfying the | ||||
| // constraint. It is left as a proof for the reader that, modulo sorting, there | ||||
| // is exactly one such normalized form. | ||||
| // | ||||
| // Because the minimal representation always takes this form, StructuralTerms | ||||
| // returns a slice of tilde terms corresponding to the terms of the union in | ||||
| // the normalized structural restriction. An error is returned if the | ||||
| // constraint interface is invalid, exceeds complexity bounds, or has an empty | ||||
| // type set. In the latter case, StructuralTerms returns ErrEmptyTypeSet. | ||||
| // | ||||
| // StructuralTerms makes no guarantees about the order of terms, except that it | ||||
| // is deterministic. | ||||
| func StructuralTerms(tparam *TypeParam) ([]*Term, error) { | ||||
| 	constraint := tparam.Constraint() | ||||
| 	if constraint == nil { | ||||
| 		return nil, fmt.Errorf("%s has nil constraint", tparam) | ||||
| 	} | ||||
| 	var embeddeds []types.Type | ||||
| 	tset, err := computeTermSet(iface, make(map[types.Type]*termSet), 0) | ||||
| 	iface, _ := constraint.Underlying().(*types.Interface) | ||||
| 	if iface == nil { | ||||
| 		return nil, fmt.Errorf("constraint is %T, not *types.Interface", constraint.Underlying()) | ||||
| 	} | ||||
| 	return InterfaceTermSet(iface) | ||||
| } | ||||
|  | ||||
| // InterfaceTermSet computes the normalized terms for a constraint interface, | ||||
| // returning an error if the term set cannot be computed or is empty. In the | ||||
| // latter case, the error will be ErrEmptyTypeSet. | ||||
| // | ||||
| // See the documentation of StructuralTerms for more information on | ||||
| // normalization. | ||||
| func InterfaceTermSet(iface *types.Interface) ([]*Term, error) { | ||||
| 	return computeTermSet(iface) | ||||
| } | ||||
|  | ||||
| // UnionTermSet computes the normalized terms for a union, returning an error | ||||
| // if the term set cannot be computed or is empty. In the latter case, the | ||||
| // error will be ErrEmptyTypeSet. | ||||
| // | ||||
| // See the documentation of StructuralTerms for more information on | ||||
| // normalization. | ||||
| func UnionTermSet(union *Union) ([]*Term, error) { | ||||
| 	return computeTermSet(union) | ||||
| } | ||||
|  | ||||
| func computeTermSet(typ types.Type) ([]*Term, error) { | ||||
| 	tset, err := computeTermSetInternal(typ, make(map[types.Type]*termSet), 0) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	switch { | ||||
| 	case tset.terms.isEmpty(): | ||||
| 		// Special case: as documented | ||||
| 	if tset.terms.isEmpty() { | ||||
| 		return nil, ErrEmptyTypeSet | ||||
| 	} | ||||
| 	if tset.terms.isAll() { | ||||
| 		return nil, nil | ||||
|  | ||||
| 	case tset.terms.isAll(): | ||||
| 		// No embeddeds. | ||||
|  | ||||
| 	case len(tset.terms) == 1: | ||||
| 		if !tset.terms[0].tilde { | ||||
| 			embeddeds = append(embeddeds, tset.terms[0].typ) | ||||
| 			break | ||||
| 		} | ||||
| 		fallthrough | ||||
| 	default: | ||||
| 		var terms []*Term | ||||
| 		for _, term := range tset.terms { | ||||
| 			terms = append(terms, NewTerm(term.tilde, term.typ)) | ||||
| 		} | ||||
| 		embeddeds = append(embeddeds, NewUnion(terms)) | ||||
| 	} | ||||
|  | ||||
| 	return types.NewInterfaceType(methods, embeddeds), nil | ||||
| } | ||||
|  | ||||
| var ErrEmptyTypeSet = errors.New("empty type set") | ||||
|  | ||||
| // StructuralTerms returns the normalized structural type restrictions of a | ||||
| // type, if any. For types that are not type parameters, it returns term slice | ||||
| // containing a single non-tilde term holding the given type. For type | ||||
| // parameters, it returns the normalized term list of the type parameter's | ||||
| // constraint. See NormalizeInterface for more information on the normal form | ||||
| // of a constraint interface. | ||||
| // | ||||
| // StructuralTerms returns an error if the structural term list cannot be | ||||
| // computed. If the type set of typ is empty, it returns ErrEmptyTypeSet. | ||||
| func StructuralTerms(typ types.Type) ([]*Term, error) { | ||||
| 	switch typ := typ.(type) { | ||||
| 	case *TypeParam: | ||||
| 		iface, _ := typ.Constraint().(*types.Interface) | ||||
| 		if iface == nil { | ||||
| 			return nil, fmt.Errorf("constraint is %T, not *types.Interface", typ) | ||||
| 		} | ||||
| 		tset, err := computeTermSet(iface, make(map[types.Type]*termSet), 0) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		if tset.terms.isEmpty() { | ||||
| 			return nil, ErrEmptyTypeSet | ||||
| 		} | ||||
| 		if tset.terms.isAll() { | ||||
| 			return nil, nil | ||||
| 		} | ||||
| 		var terms []*Term | ||||
| 		for _, term := range tset.terms { | ||||
| 			terms = append(terms, NewTerm(term.tilde, term.typ)) | ||||
| 		} | ||||
| 		return terms, nil | ||||
| 	default: | ||||
| 		return []*Term{NewTerm(false, typ)}, nil | ||||
| 	var terms []*Term | ||||
| 	for _, term := range tset.terms { | ||||
| 		terms = append(terms, NewTerm(term.tilde, term.typ)) | ||||
| 	} | ||||
| 	return terms, nil | ||||
| } | ||||
|  | ||||
| // A termSet holds the normalized set of terms for a given type. | ||||
| @ -118,7 +122,7 @@ func indentf(depth int, format string, args ...interface{}) { | ||||
| 	fmt.Fprintf(os.Stderr, strings.Repeat(".", depth)+format+"\n", args...) | ||||
| } | ||||
|  | ||||
| func computeTermSet(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { | ||||
| func computeTermSetInternal(t types.Type, seen map[types.Type]*termSet, depth int) (res *termSet, err error) { | ||||
| 	if t == nil { | ||||
| 		panic("nil type") | ||||
| 	} | ||||
| @ -159,7 +163,7 @@ func computeTermSet(t types.Type, seen map[types.Type]*termSet, depth int) (res | ||||
| 			if _, ok := embedded.Underlying().(*TypeParam); ok { | ||||
| 				return nil, fmt.Errorf("invalid embedded type %T", embedded) | ||||
| 			} | ||||
| 			tset2, err := computeTermSet(embedded, seen, depth+1) | ||||
| 			tset2, err := computeTermSetInternal(embedded, seen, depth+1) | ||||
| 			if err != nil { | ||||
| 				return nil, err | ||||
| 			} | ||||
| @ -173,7 +177,7 @@ func computeTermSet(t types.Type, seen map[types.Type]*termSet, depth int) (res | ||||
| 			var terms termlist | ||||
| 			switch t.Type().Underlying().(type) { | ||||
| 			case *types.Interface: | ||||
| 				tset2, err := computeTermSet(t.Type(), seen, depth+1) | ||||
| 				tset2, err := computeTermSetInternal(t.Type(), seen, depth+1) | ||||
| 				if err != nil { | ||||
| 					return nil, err | ||||
| 				} | ||||
|  | ||||
							
								
								
									
										1
									
								
								vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/golang.org/x/tools/internal/typeparams/typeparams_go117.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @ -75,6 +75,7 @@ func ForFuncType(*ast.FuncType) *ast.FieldList { | ||||
| // this Go version. Its methods panic on use. | ||||
| type TypeParam struct{ types.Type } | ||||
|  | ||||
| func (*TypeParam) Index() int             { unsupported(); return 0 } | ||||
| func (*TypeParam) Constraint() types.Type { unsupported(); return nil } | ||||
| func (*TypeParam) Obj() *types.TypeName   { unsupported(); return nil } | ||||
|  | ||||
|  | ||||
							
								
								
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @ -73,7 +73,7 @@ golang.org/x/sys/execabs | ||||
| golang.org/x/sys/internal/unsafeheader | ||||
| golang.org/x/sys/unix | ||||
| golang.org/x/sys/windows | ||||
| # golang.org/x/tools v0.1.8-0.20211028023602-8de2a7fd1736 | ||||
| # golang.org/x/tools v0.1.8 | ||||
| ## explicit | ||||
| golang.org/x/tools/go/gcexportdata | ||||
| golang.org/x/tools/go/internal/gcimporter | ||||
|  | ||||
		Reference in New Issue
	
	Block a user