// apparent when we first created the instantiation of the generic function.
// We can't handle this if we actually do the inlining, since we want to know
// all interface conversions immediately after stenciling. So, we avoid
- // inlining in this case. See #49309.
+ // inlining in this case. See #49309. (1)
if !fn.Type().HasShape() {
for _, arg := range n.Args {
if arg.Type().HasShape() {
return n
}
}
+ } else {
+ // Don't inline a function fn that has shape parameters, but is passed no shape arg.
+ // See comments (1) above, and issue #51909
+ inlineable := false
+ for _, arg := range n.Args {
+ if arg.Type().HasShape() {
+ inlineable = true
+ break
+ }
+ }
+ if !inlineable {
+ if logopt.Enabled() {
+ logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
+ fmt.Sprintf("inlining shape function %v with no shape args", ir.FuncName(fn)))
+ }
+ return n
+ }
}
if base.Flag.Cfg.Instrumenting && types.IsRuntimePkg(fn.Sym().Pkg) {
--- /dev/null
+// compile
+
+// 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
+
+type None struct{}
+
+type Response interface {
+ send(ctx *struct{})
+}
+
+type HandlerFunc[Input any] func(Input) Response
+
+func Operation[Input any](method, path string, h HandlerFunc[Input]) {
+ var input Input
+ h(input)
+}
+
+func Get[Body any](path string, h HandlerFunc[struct{ Body Body }]) {
+ Operation("GET", path, h)
+}
+
+func main() {
+ Get("/", func(req struct{ Body None }) Response {
+ return nil
+ })
+}
--- /dev/null
+// compile
+
+// 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"
+
+type IntLike interface {
+ ~int | ~int64 | ~int32 | ~int16 | ~int8
+}
+
+func Reduce[T any, U any, Uslice ~[]U](function func(T, U) T, sequence Uslice, initial T) T {
+ result := initial
+ for _, x := range sequence {
+ result = function(result, x)
+ }
+ return result
+}
+
+func min[T IntLike](x, y T) T {
+ if x < y {
+ return x
+ }
+ return y
+
+}
+
+// Min returns the minimum element of `nums`.
+func Min[T IntLike, NumSlice ~[]T](nums NumSlice) T {
+ if len(nums) == 0 {
+ return T(0)
+ }
+ return Reduce(min[T], nums, nums[0])
+}
+
+// VarMin is the variadic version of Min.
+func VarMin[T IntLike](nums ...T) T {
+ return Min(nums)
+}
+
+type myInt int
+
+func main() {
+ fmt.Println(VarMin(myInt(1), myInt(2)))
+
+ seq := []myInt{1, 2}
+ fmt.Println(Min(seq))
+ fmt.Println(VarMin(seq...))
+}