From 4545287c1be25b487dd804b5bc010315cfc5fea5 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Mon, 6 Jul 2020 19:58:02 -0700 Subject: [PATCH] [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 --- src/go/types/call.go | 13 +++++++------ src/go/types/fixedbugs/issue40056.go2 | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 src/go/types/fixedbugs/issue40056.go2 diff --git a/src/go/types/call.go b/src/go/types/call.go index 459d0dd127..d3cfc63bbc 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -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 = © } - 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.) diff --git a/src/go/types/fixedbugs/issue40056.go2 b/src/go/types/fixedbugs/issue40056.go2 new file mode 100644 index 0000000000..b0afd6c1c9 --- /dev/null +++ b/src/go/types/fixedbugs/issue40056.go2 @@ -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() \ No newline at end of file