summaryrefslogtreecommitdiff
path: root/src/go/types/index.go
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2023-03-13 16:38:14 -0700
committerGopher Robot <gobot@golang.org>2023-03-29 20:53:08 +0000
commitcc048b32f3de4168de6b0207fd01c65e51d37ac0 (patch)
treea8dc26316b4550692afb9acb97c88485e5c85451 /src/go/types/index.go
parent93b3035dbbcd21c1d0538142cba4e7f79631e7a2 (diff)
downloadgo-git-cc048b32f3de4168de6b0207fd01c65e51d37ac0.tar.gz
go/types, types2: reverse inference of function type arguments
This CL implements type inference for generic functions used in assignments: variable init expressions, regular assignments, and return statements, but (not yet) function arguments passed to functions. For instance, given a generic function func f[P any](x P) and a variable of function type var v func(x int) the assignment v = f is valid w/o explicit instantiation of f, and the missing type argument for f is inferred from the type of v. More generally, the function f may have multiple type arguments, and it may be partially instantiated. This new form of inference is not enabled by default (it needs to go through the proposal process first). It can be enabled by setting Config.EnableReverseTypeInference. The mechanism is implemented as follows: - The various expression evaluation functions take an additional (first) argument T, which is the target type for the expression. If not nil, it is the type of the LHS in an assignment. - The method Checker.funcInst is changed such that it uses both, provided type arguments (if any), and a target type (if any) to augment type inference. Change-Id: Idfde61078e1ee4f22abcca894a4c84d681734ff6 Reviewed-on: https://go-review.googlesource.com/c/go/+/476075 TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Robert Griesemer <gri@google.com> Run-TryBot: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src/go/types/index.go')
-rw-r--r--src/go/types/index.go10
1 files changed, 5 insertions, 5 deletions
diff --git a/src/go/types/index.go b/src/go/types/index.go
index 2fcc3f3492..1bcfb38feb 100644
--- a/src/go/types/index.go
+++ b/src/go/types/index.go
@@ -43,7 +43,7 @@ func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst
}
// x should not be generic at this point, but be safe and check
- check.nonGeneric(x)
+ check.nonGeneric(nil, x)
if x.mode == invalid {
return false
}
@@ -93,7 +93,7 @@ func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst
return false
}
var key operand
- check.expr(&key, index)
+ check.expr(nil, &key, index)
check.assignment(&key, typ.key, "map index")
// ok to continue even if indexing failed - map element type is known
x.mode = mapindex
@@ -167,7 +167,7 @@ func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst
return false
}
var k operand
- check.expr(&k, index)
+ check.expr(nil, &k, index)
check.assignment(&k, key, "map index")
// ok to continue even if indexing failed - map element type is known
x.mode = mapindex
@@ -208,7 +208,7 @@ func (check *Checker) indexExpr(x *operand, e *typeparams.IndexExpr) (isFuncInst
}
func (check *Checker) sliceExpr(x *operand, e *ast.SliceExpr) {
- check.expr(x, e.X)
+ check.expr(nil, x, e.X)
if x.mode == invalid {
check.use(e.Low, e.High, e.Max)
return
@@ -350,7 +350,7 @@ func (check *Checker) index(index ast.Expr, max int64) (typ Type, val int64) {
val = -1
var x operand
- check.expr(&x, index)
+ check.expr(nil, &x, index)
if !check.isValidIndex(&x, InvalidIndex, "index", false) {
return
}