diff options
Diffstat (limited to 'typeparams/example/predicates/main.go')
-rw-r--r-- | typeparams/example/predicates/main.go | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/typeparams/example/predicates/main.go b/typeparams/example/predicates/main.go new file mode 100644 index 0000000..5237c06 --- /dev/null +++ b/typeparams/example/predicates/main.go @@ -0,0 +1,114 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "go/ast" + "go/parser" + "go/token" + "go/types" + "log" + + "golang.org/x/exp/typeparams" +) + +const src = ` +//!+input +package p + +type Pair[L, R comparable] struct { + left L + right R +} + +func (p Pair[L, _]) Left() L { + return p.left +} + +func (p Pair[_, R]) Right() R { + return p.right +} + +// M does not use type parameters, and therefore implements the Mer interface. +func (p Pair[_, _]) M() int { return 0 } + +type LeftRighter[L, R comparable] interface { + Left() L + Right() R +} + +type Mer interface { + M() int +} + +// F and G have identical signatures "modulo renaming", H does not. +func F[P any](P) int { return 0 } +func G[Q any](Q) int { return 1 } +func H[R ~int](R) int { return 2 } +//!-input +` + +// !+ordinary +func OrdinaryPredicates(pkg *types.Package) { + var ( + Pair = pkg.Scope().Lookup("Pair").Type() + LeftRighter = pkg.Scope().Lookup("LeftRighter").Type() + Mer = pkg.Scope().Lookup("Mer").Type() + F = pkg.Scope().Lookup("F").Type() + G = pkg.Scope().Lookup("G").Type() + H = pkg.Scope().Lookup("H").Type() + ) + + fmt.Println("AssignableTo(Pair, LeftRighter)", types.AssignableTo(Pair, LeftRighter)) + fmt.Println("AssignableTo(Pair, Mer): ", types.AssignableTo(Pair, Mer)) + fmt.Println("Identical(F, G)", types.Identical(F, G)) + fmt.Println("Identical(F, H)", types.Identical(F, H)) +} + +//!-ordinary + +/* +//!+ordinaryoutput +AssignableTo(Pair, LeftRighter) false +AssignableTo(Pair, Mer): true +Identical(F, G) true +Identical(F, H) false +//!-ordinaryoutput +*/ + +// !+generic +func GenericPredicates(pkg *types.Package) { + var ( + Pair = pkg.Scope().Lookup("Pair").Type() + LeftRighter = pkg.Scope().Lookup("LeftRighter").Type() + ) + fmt.Println("GenericAssignableTo(Pair, LeftRighter)", typeparams.GenericAssignableTo(nil, Pair, LeftRighter)) +} + +//!-generic + +/* +//!+genericoutput +GenericAssignableTo(Pair, LeftRighter) true +//!-genericoutput +*/ + +func main() { + fset := token.NewFileSet() + f, err := parser.ParseFile(fset, "hello.go", src, 0) + if err != nil { + log.Fatal(err) + } + conf := types.Config{} + pkg, err := conf.Check("p", fset, []*ast.File{f}, nil) + if err != nil { + log.Fatal(err) + } + fmt.Println("=== ordinary ===") + OrdinaryPredicates(pkg) + fmt.Println("=== generic ===") + GenericPredicates(pkg) +} |