Skip to content

Commit 414af50

Browse files
committed
go/types: fix type inference
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>
1 parent c96fec9 commit 414af50

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

src/go/types/fixedbugs/issue44799.go2

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,3 @@ func main() {
1717
_ = Reduce[int](s, 0, f2)
1818
_ = Reduce(s, 0, f2)
1919
}
20-
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package p
6+
7+
func f[F interface{type *Q}, G interface{type *R}, Q, R any](q Q, r R) {}
8+
9+
func _() {
10+
f[*float64, *int](1, 2)
11+
f[*float64](1, 2)
12+
f(1, 2)
13+
}

src/go/types/infer.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,25 @@ func (check *Checker) inferB(tparams []*TypeName, targs []Type, report bool) (ty
446446
dirty = dirty[:n]
447447
}
448448

449+
// Once nothing changes anymore, we may still have type parameters left;
450+
// e.g., a structural constraint *P may match a type parameter Q but we
451+
// don't have any type arguments to fill in for *P or Q (issue #45548).
452+
// Don't let such inferences escape, instead nil them out.
453+
for i, typ := range types {
454+
if typ != nil && isParameterized(tparams, typ) {
455+
types[i] = nil
456+
}
457+
}
458+
459+
// update index
460+
index = -1
461+
for i, typ := range types {
462+
if typ == nil {
463+
index = i
464+
break
465+
}
466+
}
467+
449468
return
450469
}
451470

src/go/types/unify.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package types
88

99
import (
10+
"bytes"
1011
"go/token"
1112
"sort"
1213
)
@@ -74,6 +75,22 @@ type tparamsList struct {
7475
indices []int // len(d.indices) == len(d.tparams)
7576
}
7677

78+
// String returns a string representation for a tparamsList. For debugging.
79+
func (d *tparamsList) String() string {
80+
var buf bytes.Buffer
81+
buf.WriteByte('[')
82+
for i, tname := range d.tparams {
83+
if i > 0 {
84+
buf.WriteString(", ")
85+
}
86+
writeType(&buf, tname.typ, nil, nil)
87+
buf.WriteString(": ")
88+
writeType(&buf, d.at(i), nil, nil)
89+
}
90+
buf.WriteByte(']')
91+
return buf.String()
92+
}
93+
7794
// init initializes d with the given type parameters.
7895
// The type parameters must be in the order in which they appear in their declaration
7996
// (this ensures that the tparams indices match the respective type parameter index).

0 commit comments

Comments
 (0)