mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
c96fec9036
commit
414af503d7
4 changed files with 49 additions and 1 deletions
|
|
@ -17,4 +17,3 @@ func main() {
|
||||||
_ = Reduce[int](s, 0, f2)
|
_ = Reduce[int](s, 0, f2)
|
||||||
_ = Reduce(s, 0, f2)
|
_ = Reduce(s, 0, f2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
13
src/go/types/fixedbugs/issue45548.go2
Normal file
13
src/go/types/fixedbugs/issue45548.go2
Normal file
|
|
@ -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)
|
||||||
|
}
|
||||||
|
|
@ -446,6 +446,25 @@ func (check *Checker) inferB(tparams []*TypeName, targs []Type, report bool) (ty
|
||||||
dirty = dirty[:n]
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"go/token"
|
"go/token"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
@ -74,6 +75,22 @@ type tparamsList struct {
|
||||||
indices []int // len(d.indices) == len(d.tparams)
|
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.
|
// init initializes d with the given type parameters.
|
||||||
// The type parameters must be in the order in which they appear in their declaration
|
// 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).
|
// (this ensures that the tparams indices match the respective type parameter index).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue