if i > 0 {
b.WriteString(",")
}
- b.WriteString(targ.Name().Sym().Name)
+ b.WriteString(targ.Type().String())
}
b.WriteString("]")
return typecheck.Lookup(b.String())
newf.Nname = ir.NewNameAt(inst.Pos(), name)
newf.Nname.Func = newf
newf.Nname.Defn = newf
+ name.Def = newf.Nname
subst := &subster{
newf: newf,
m.SetType(newt)
m.Curfn = subst.newf
m.Class = name.Class
+ m.Func = name.Func
subst.vars[name] = m
m.SetTypecheck(1)
return m
}
m := ir.Copy(x)
if _, isExpr := m.(ir.Expr); isExpr {
- m.SetType(subst.typ(x.Type()))
+ t := x.Type()
+ if t == nil {
+ // t can be nil only if this is a call that has no
+ // return values, so allow that and otherwise give
+ // an error.
+ if _, isCallExpr := m.(*ir.CallExpr); !isCallExpr {
+ base.Fatalf(fmt.Sprintf("Nil type for %v", x))
+ }
+ } else {
+ m.SetType(subst.typ(x.Type()))
+ }
}
ir.EditChildren(m, edit)
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2021 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"
+)
+
+// Index returns the index of x in s, or -1 if not found.
+func index[T comparable](s []T, x T) int {
+ for i, v := range s {
+ // v and x are type T, which has the comparable
+ // constraint, so we can use == here.
+ if v == x {
+ return i
+ }
+ }
+ return -1
+}
+
+type obj struct {
+ x int
+}
+
+func main() {
+ want := 2
+
+ vec1 := []string{"ab", "cd", "ef"}
+ if got := index(vec1, "ef"); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+
+ vec2 := []byte{'c', '6', '@'}
+ if got := index(vec2, '@'); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+
+ vec3 := []*obj{&obj{2}, &obj{42}, &obj{1}}
+ if got := index(vec3, vec3[2]); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+}
got := mapper([]int{1, 2, 3}, strconv.Itoa)
want := []string{"1", "2", "3"}
if !reflect.DeepEqual(got, want) {
- panic(fmt.Sprintf("Got %s, want %s", got, want))
+ panic(fmt.Sprintf("got %s, want %s", got, want))
}
fgot := mapper([]float64{2.5, 2.3, 3.5}, func(f float64) string {
})
fwant := []string{"2.5", "2.3", "3.5"}
if !reflect.DeepEqual(fgot, fwant) {
- panic(fmt.Sprintf("Got %s, want %s", fgot, fwant))
+ panic(fmt.Sprintf("got %s, want %s", fgot, fwant))
}
}
"fmt"
)
+type Ordered interface {
+ type int, int64, float64
+}
-func min[T interface{ type int }](x, y T) T {
+func min[T Ordered](x, y T) T {
if x < y {
return x
}
}
func main() {
- want := 2
- got := min[int](2, 3)
- if want != got {
- panic(fmt.Sprintf("Want %d, got %d", want, got))
+ const want = 2
+ if got := min[int](2, 3); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
+ }
+
+ if got := min(2, 3); got != want {
+ panic(fmt.Sprintf("want %d, got %d", want, got))
+ }
+
+ if got := min[float64](3.5, 2.0); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
}
- got = min(2, 3)
- if want != got {
- panic(fmt.Sprintf("Want %d, got %d", want, got))
+ if got := min(3.5, 2.0); got != want {
+ panic(fmt.Sprintf("got %d, want %d", got, want))
}
}
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2021 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"
+ "strconv"
+)
+
+func fromStrings3[T any](s []string, set func(*T, string)) []T {
+ results := make([]T, len(s))
+ for i, v := range s {
+ set(&results[i], v)
+ }
+ return results
+}
+
+type Settable int
+
+func (p *Settable) Set(s string) {
+ i, err := strconv.Atoi(s)
+ if err != nil {
+ panic(err)
+ }
+ *p = Settable(i)
+}
+
+func main() {
+ s := fromStrings3([]string{"1"},
+ func(p *Settable, s string) { p.Set(s) })
+ if len(s) != 1 || s[0] != 1 {
+ panic(fmt.Sprintf("got %v, want %v", s, []int{1}))
+ }
+}
--- /dev/null
+// run -gcflags=-G=3
+
+// Copyright 2021 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"
+)
+
+type Ordered interface {
+ type int, int8, int16, int32, int64,
+ uint, uint8, uint16, uint32, uint64, uintptr,
+ float32, float64,
+ string
+}
+
+func smallest[T Ordered](s []T) T {
+ r := s[0] // panics if slice is empty
+ for _, v := range s[1:] {
+ if v < r {
+ r = v
+ }
+ }
+ return r
+}
+
+func main() {
+ vec1 := []float64{5.3, 1.2, 32.8}
+ vec2 := []string{"abc", "def", "aaa"}
+
+ want1 := 1.2
+ if got := smallest(vec1); got != want1 {
+ panic(fmt.Sprintf("got %d, want %d", got, want1))
+ }
+ want2 := "aaa"
+ if got := smallest(vec2); got != want2 {
+ panic(fmt.Sprintf("got %d, want %d", got, want2))
+ }
+}
got := stringify(x)
want := []string{"1", "2", "3"}
if !reflect.DeepEqual(got, want) {
- panic(fmt.Sprintf("Got %s, want %s", got, want))
+ panic(fmt.Sprintf("got %s, want %s", got, want))
}
got = stringify2(x)
if !reflect.DeepEqual(got, want) {
- panic(fmt.Sprintf("Got %s, want %s", got, want))
+ panic(fmt.Sprintf("got %s, want %s", got, want))
}
got = stringify3(x)
if !reflect.DeepEqual(got, want) {
- panic(fmt.Sprintf("Got %s, want %s", got, want))
+ panic(fmt.Sprintf("got %s, want %s", got, want))
}
}
got := sum[int](vec1)
want := vec1[0] + vec1[1]
if got != want {
- panic(fmt.Sprintf("Got %d, want %d", got, want))
+ panic(fmt.Sprintf("got %d, want %d", got, want))
}
got = sum(vec1)
if want != got {
- panic(fmt.Sprintf("Got %d, want %d", got, want))
+ panic(fmt.Sprintf("got %d, want %d", got, want))
}
fwant := vec2[0] + vec2[1]
fgot := sum[float64](vec2)
if abs(fgot - fwant) > 1e-10 {
- panic(fmt.Sprintf("Got %f, want %f", fgot, fwant))
+ panic(fmt.Sprintf("got %f, want %f", fgot, fwant))
}
fgot = sum(vec2)
if abs(fgot - fwant) > 1e-10 {
- panic(fmt.Sprintf("Got %f, want %f", fgot, fwant))
+ panic(fmt.Sprintf("got %f, want %f", fgot, fwant))
}
}