]> Cypherpunks repositories - gostls13.git/commitdiff
go/types: fix type inference
authorRob Findley <rfindley@google.com>
Wed, 28 Apr 2021 14:07:18 +0000 (10:07 -0400)
committerRobert Findley <rfindley@google.com>
Wed, 28 Apr 2021 20:21:24 +0000 (20:21 +0000)
This is a 1:1 port of CL 311651 to go/types.

Change-Id: I9d91b45cc5fa7ce686d6a91d4dde274d9f80e0d7
Reviewed-on: https://go-review.googlesource.com/c/go/+/314595
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/fixedbugs/issue44799.go2
src/go/types/fixedbugs/issue45548.go2 [new file with mode: 0644]
src/go/types/infer.go
src/go/types/unify.go

index 33f2c9a25c1ebd6a2f2805b10e6b3426c6f647a5..9e528a7475b30e02792def3c31274c37e852e618 100644 (file)
@@ -17,4 +17,3 @@ func main() {
        _ = Reduce[int](s, 0, f2)
        _ = Reduce(s, 0, f2)
 }
-
diff --git a/src/go/types/fixedbugs/issue45548.go2 b/src/go/types/fixedbugs/issue45548.go2
new file mode 100644 (file)
index 0000000..b1e4249
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 p
+
+func f[F interface{type *Q}, G interface{type *R}, Q, R any](q Q, r R) {}
+
+func _() {
+       f[*float64, *int](1, 2)
+       f[*float64](1, 2)
+       f(1, 2)
+}
index 9a45d5e9940e6760cef8047c5d82358702bddb76..da3a521870244a06fc5adc16b1db8d17c3f813f5 100644 (file)
@@ -446,6 +446,25 @@ func (check *Checker) inferB(tparams []*TypeName, targs []Type, report bool) (ty
                dirty = dirty[:n]
        }
 
+       // Once nothing changes anymore, we may still have type parameters left;
+       // e.g., a structural constraint *P may match a type parameter Q but we
+       // don't have any type arguments to fill in for *P or Q (issue #45548).
+       // Don't let such inferences escape, instead nil them out.
+       for i, typ := range types {
+               if typ != nil && isParameterized(tparams, typ) {
+                       types[i] = nil
+               }
+       }
+
+       // update index
+       index = -1
+       for i, typ := range types {
+               if typ == nil {
+                       index = i
+                       break
+               }
+       }
+
        return
 }
 
index fbcd64c4428393afd8f6629417739646a112d79f..db06e21cf724fd11330e33f0c91ffe03ce09138a 100644 (file)
@@ -7,6 +7,7 @@
 package types
 
 import (
+       "bytes"
        "go/token"
        "sort"
 )
@@ -74,6 +75,22 @@ type tparamsList struct {
        indices []int // len(d.indices) == len(d.tparams)
 }
 
+// String returns a string representation for a tparamsList. For debugging.
+func (d *tparamsList) String() string {
+       var buf bytes.Buffer
+       buf.WriteByte('[')
+       for i, tname := range d.tparams {
+               if i > 0 {
+                       buf.WriteString(", ")
+               }
+               writeType(&buf, tname.typ, nil, nil)
+               buf.WriteString(": ")
+               writeType(&buf, d.at(i), nil, nil)
+       }
+       buf.WriteByte(']')
+       return buf.String()
+}
+
 // init initializes d with the given type parameters.
 // The type parameters must be in the order in which they appear in their declaration
 // (this ensures that the tparams indices match the respective type parameter index).