go/types: fix a type instantiation issue, added slices.go2 example

Change-Id: If020572762039adf10973bccd072005084e17e4e
This commit is contained in:
Robert Griesemer 2019-08-01 17:13:34 -07:00
parent c4a20af9f1
commit d03ba9f74c
3 changed files with 83 additions and 6 deletions

63
src/go/types/testdata/slices.go2 vendored Normal file
View File

@ -0,0 +1,63 @@
// Package slices implements various slice algorithms.
package slices
// Map turns a []T1 to a []T2 using a mapping function.
func Map(type T1, T2)(s []T1, f func(T1) T2) []T2 {
r := make([]T2, len(s))
for i, v := range s {
r[i] = f(v)
}
return r
}
// Reduce reduces a []T1 to a single value using a reduction function.
func Reduce(type T1, T2)(s []T1, initializer T2, f func(T2, T1) T2) T2 {
r := initializer
for _, v := range s {
r = f(r, v)
}
return r
}
// Filter filters values from a slice using a filter function.
func Filter(type T)(s []T, f func(T) bool) []T {
var r []T
for _, v := range s {
if f(v) {
r = append(r, v)
}
}
return r
}
// Example uses
func limiter(x int) byte {
switch {
case x < 0:
return 0
default:
return byte(x)
case x > 255:
return 255
}
}
var input = []int{-4, 68954, 7, 44, 0, -555, 6945}
var limited1 = Map(int, byte)(input, limiter)
var limited2 = Map(input, limiter) // using type inference
func reducer(x float64, y int) float64 {
return x + float64(y)
}
var reduced1 = Reduce(int, float64)(input, 0, reducer)
var reduced2 = Reduce(input, 1.0, reducer) // using type inference
func filter(x int) bool {
return x&1 != 0
}
var filtered1 = Filter(int)(input, filter)
var filtered2 = Filter(input, filter) // using type inference

View File

@ -1,8 +1,18 @@
package p
func Ranger(type T)() (*Receiver(T)) {
//return &Receiver(T){} // TODO(gri) make this work
return nil
func Reduce(type T1, T2)(s []T1, initializer T2, f func(T2, T1) T2) T2 {
r := initializer
for _, v := range s {
r = f(r, v)
}
return r
}
type Receiver(type T) struct {}
func reducer(float64, int) float64 {
return 0
}
var _ = Reduce([]int{}, 1.0, reducer)
// TODO(gri) investigate - seems like type inference should accept 1 here
// var _ = Reduce([]int{}, 1, reducer)

View File

@ -143,10 +143,14 @@ func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) {
}
// instantiatedType is like typ but it ensures that a Parametrized type is
// fully instantiated.
// fully instantiated if all type parameters are known.
// (When we type-check a parameterized function body, parameterized types
// whose type parameters are incoming parameters cannot be instantiated.)
func (check *Checker) instantiatedType(e ast.Expr) Type {
typ := check.typ(e)
if ptyp, _ := typ.(*Parameterized); ptyp != nil {
// A parameterized type where all type arguments are known
// (i.e., not type parameters themselves) can be instantiated.
if ptyp, _ := typ.(*Parameterized); ptyp != nil && !isParameterized(ptyp) {
typ = check.inst(ptyp.tname, ptyp.targs)
// TODO(gri) can this ever be nil? comment.
if typ == nil {