[dev.go2go] go/types: don't panic if receiver type arguments cannot be inferred

This can happen due to earlier errors. This change avoids the panic
but reports a follow-up error. Not ideal, but good enough for now.

Fixes #40056.

Change-Id: I500d4fc2b058cdc70f28883ff8d004df4b43fe4e
Reviewed-on: https://go-review.googlesource.com/c/go/+/241130
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Robert Griesemer 2020-07-06 19:58:02 -07:00
parent 17564d8957
commit 4545287c1b
2 changed files with 22 additions and 6 deletions

View File

@ -522,7 +522,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
// The method may have a pointer receiver, but the actually provided receiver
// may be a (hopefully addressable) non-pointer value, or vice versa. Here we
// only care about inferring receiver type parameters; to make the inferrence
// work, match up pointer-ness of reveiver and argument.
// work, match up pointer-ness of receiver and argument.
arg := x
if ptrRecv := isPointer(sig.recv.typ); ptrRecv != isPointer(arg.typ) {
copy := *arg
@ -533,12 +533,13 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
}
arg = &copy
}
targs := check.infer(sig.recv.pos, sig.rparams, NewTuple(sig.recv), []*operand{arg})
targs := check.infer(sig.rparams[0].Pos(), sig.rparams, NewTuple(sig.recv), []*operand{arg})
//check.dump("### inferred targs = %s", targs)
if len(targs) == 0 {
// TODO(gri) Provide explanation as to why we can't possibly
// reach here (consider invalid receivers, etc.).
panic("internal error: receiver type parameter inference failed")
if targs == nil {
// We may reach here if there were other errors (see issue #40056).
// check.infer will report a follow-up error.
// TODO(gri) avoid the follow-up error or provide better explanation.
goto Error
}
// Don't modify m. Instead - for now - make a copy of m and use that instead.
// (If we modify m, some tests will fail; possibly because the m is in use.)

View File

@ -0,0 +1,15 @@
// Copyright 2020 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 _() {
NewS() /* ERROR cannot infer T */ .M()
}
type S struct {}
func NewS(type T)() *S
func (_ *S /* ERROR S is not a generic type */ (T /* ERROR cannot infer T */ )) M()