Skip to content

Commit

Permalink
go/types, types2: factor out type parameter renaming from type inference
Browse files Browse the repository at this point in the history
Preparation for reverse type inference where there is no need
to rename all type parameters supplied to type inference when
passing generic functions as arguments to (possibly generic)
function calls.

This also leads to a better separation of concerns.

Change-Id: Id487a5c1340b743519b9053edc43f8aa99408522
Reviewed-on: https://go-review.googlesource.com/c/go/+/484655
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Robert Griesemer <[email protected]>
Run-TryBot: Robert Griesemer <[email protected]>
Auto-Submit: Robert Griesemer <[email protected]>
Reviewed-by: Robert Findley <[email protected]>
  • Loading branch information
griesemer authored and gopherbot committed Apr 17, 2023
1 parent d259a50 commit 57678d5
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 20 deletions.
14 changes: 11 additions & 3 deletions src/cmd/compile/internal/types2/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,11 @@ func (check *Checker) funcInst(tsig *Signature, pos syntax.Pos, x *operand, inst
}
}

// Rename type parameters to avoid problems with recursive instantiations.
// Note that NewTuple(params...) below is nil if len(params) == 0, as desired.
targs = check.infer(pos, sig.TypeParams().list(), targs, NewTuple(params...), args)
tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))

targs = check.infer(pos, tparams, targs, params2, args)
if targs == nil {
// error was already reported
x.mode = invalid
Expand Down Expand Up @@ -457,7 +460,12 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
check.versionErrorf(call.Pos(), "go1.18", "implicit function instantiation")
}
}
targs := check.infer(call.Pos(), sig.TypeParams().list(), targs, sigParams, args)

// Rename type parameters to avoid problems with recursive calls.
var tparams []*TypeParam
tparams, sigParams = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)

targs := check.infer(call.Pos(), tparams, targs, sigParams, args)
if targs == nil {
return // error already reported
}
Expand All @@ -471,7 +479,7 @@ func (check *Checker) arguments(call *syntax.CallExpr, sig *Signature, targs []T
// need to compute it from the adjusted list; otherwise we can
// simply use the result signature's parameter list.
if adjusted {
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.TypeParams().list(), targs), nil, check.context()).(*Tuple)
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams, targs), nil, check.context()).(*Tuple)
} else {
sigParams = rsig.params
}
Expand Down
12 changes: 5 additions & 7 deletions src/cmd/compile/internal/types2/infer.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,6 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
}
// len(targs) < n

// Rename type parameters to avoid conflicts in recursive instantiation scenarios.
tparams, params = check.renameTParams(pos, tparams, params)

if traceInference {
check.dump("-- rename: %s%s ➞ %s\n", tparams, params, targs)
}

// Make sure we have a "full" list of type arguments, some of which may
// be nil (unknown). Make a copy so as to not clobber the incoming slice.
if len(targs) < n {
Expand Down Expand Up @@ -390,6 +383,7 @@ func (check *Checker) infer(pos syntax.Pos, tparams []*TypeParam, targs []Type,
// renameTParams renames the type parameters in a function signature described by its
// type and ordinary parameters (tparams and params) such that each type parameter is
// given a new identity. renameTParams returns the new type and ordinary parameters.
// The positions is only used for debug traces.
func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, params *Tuple) ([]*TypeParam, *Tuple) {
// For the purpose of type inference we must differentiate type parameters
// occurring in explicit type or value function arguments from the type
Expand Down Expand Up @@ -418,6 +412,10 @@ func (check *Checker) renameTParams(pos syntax.Pos, tparams []*TypeParam, params
//
// Type parameter renaming turns the first example into the second
// example by renaming the type parameter P into P2.
if len(tparams) == 0 {
return nil, params // nothing to do
}

tparams2 := make([]*TypeParam, len(tparams))
for i, tparam := range tparams {
tname := NewTypeName(tparam.Obj().Pos(), tparam.Obj().Pkg(), tparam.Obj().Name(), nil)
Expand Down
14 changes: 11 additions & 3 deletions src/go/types/call.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,11 @@ func (check *Checker) funcInst(tsig *Signature, pos token.Pos, x *operand, ix *t
}
}

// Rename type parameters to avoid problems with recursive instantiations.
// Note that NewTuple(params...) below is nil if len(params) == 0, as desired.
targs = check.infer(atPos(pos), sig.TypeParams().list(), targs, NewTuple(params...), args)
tparams, params2 := check.renameTParams(pos, sig.TypeParams().list(), NewTuple(params...))

targs = check.infer(atPos(pos), tparams, targs, params2, args)
if targs == nil {
// error was already reported
x.mode = invalid
Expand Down Expand Up @@ -460,7 +463,12 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
check.softErrorf(inNode(call, call.Lparen), UnsupportedFeature, "implicit function instantiation requires go1.18 or later")
}
}
targs := check.infer(call, sig.TypeParams().list(), targs, sigParams, args)

// Rename type parameters to avoid problems with recursive calls.
var tparams []*TypeParam
tparams, sigParams = check.renameTParams(call.Pos(), sig.TypeParams().list(), sigParams)

targs := check.infer(call, tparams, targs, sigParams, args)
if targs == nil {
return // error already reported
}
Expand All @@ -474,7 +482,7 @@ func (check *Checker) arguments(call *ast.CallExpr, sig *Signature, targs []Type
// need to compute it from the adjusted list; otherwise we can
// simply use the result signature's parameter list.
if adjusted {
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(sig.TypeParams().list(), targs), nil, check.context()).(*Tuple)
sigParams = check.subst(call.Pos(), sigParams, makeSubstMap(tparams, targs), nil, check.context()).(*Tuple)
} else {
sigParams = rsig.params
}
Expand Down
12 changes: 5 additions & 7 deletions src/go/types/infer.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 57678d5

Please sign in to comment.