summaryrefslogtreecommitdiffstats
path: root/typeparams/example/predicates/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'typeparams/example/predicates/main.go')
-rw-r--r--typeparams/example/predicates/main.go114
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)
+}