Fixes #49541.
Change-Id: I27a52d0722a7408758682e7ddcd608c0a6c4881b
Reviewed-on: https://go-review.googlesource.com/c/go/+/378175
Trust: Robert Griesemer <gri@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
if obj == nil {
+ // Don't report another error if the underlying type was invalid (issue #49541).
+ if under(x.typ) == Typ[Invalid] {
+ goto Error
+ }
+
if index != nil {
// TODO(gri) should provide actual type where the conflict happens
check.errorf(e.Sel, "ambiguous selector %s.%s", x.expr, sel)
Vu := under(V)
Tu := under(T)
if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
- return nil
+ return nil // avoid follow-on errors
+ }
+ if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
+ return nil // avoid follow-on errors (see issue #49541 for an example)
}
errorf := func(format string, args ...interface{}) error {
--- /dev/null
+// Copyright 2022 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
+
+type S[A, B any] struct {
+ f int
+}
+
+func (S[A, B]) m() {}
+
+// TODO(gri) We should only report one error below. See issue #50588.
+
+func _[A any](s S /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [A]) {
+ // we should see no follow-on errors below
+ s.f = 1
+ s.m()
+}
+
+// another test case from the issue
+
+func _() {
+ X(Interface[*F /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [string]](Impl{}))
+}
+
+func X[Q Qer](fs Interface[Q]) {
+}
+
+type Impl struct{}
+
+func (Impl) M() {}
+
+type Interface[Q Qer] interface {
+ M()
+}
+
+type Qer interface {
+ Q()
+}
+
+type F[A, B any] struct{}
+
+func (f *F[A, B]) Q() {}
// underIs calls f with the underlying types of the specific type terms
// of s and reports whether all calls to f returned true. If there are
-// no specific terms, is returns the result of f(nil).
+// no specific terms, underIs returns the result of f(nil).
func (s *_TypeSet) underIs(f func(Type) bool) bool {
if !s.hasTerms() {
return f(nil)
obj, index, indirect = LookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, sel)
if obj == nil {
+ // Don't report another error if the underlying type was invalid (issue #49541).
+ if under(x.typ) == Typ[Invalid] {
+ goto Error
+ }
+
if index != nil {
// TODO(gri) should provide actual type where the conflict happens
check.errorf(e.Sel, _AmbiguousSelector, "ambiguous selector %s.%s", x.expr, sel)
Vu := under(V)
Tu := under(T)
if Vu == Typ[Invalid] || Tu == Typ[Invalid] {
- return nil
+ return nil // avoid follow-on errors
+ }
+ if p, _ := Vu.(*Pointer); p != nil && under(p.base) == Typ[Invalid] {
+ return nil // avoid follow-on errors (see issue #49541 for an example)
}
errorf := func(format string, args ...any) error {
--- /dev/null
+// Copyright 2022 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
+
+type S[A, B any] struct {
+ f int
+}
+
+func (S[A, B]) m() {}
+
+// TODO(gri) We should only report one error below. See issue #50588.
+
+func _[A any](s S /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [A]) {
+ // we should see no follow-on errors below
+ s.f = 1
+ s.m()
+}
+
+// another test case from the issue
+
+func _() {
+ X(Interface[*F /* ERROR cannot infer B */ /* ERROR got 1 arguments but 2 type parameters */ [string]](Impl{}))
+}
+
+func X[Q Qer](fs Interface[Q]) {
+}
+
+type Impl struct{}
+
+func (Impl) M() {}
+
+type Interface[Q Qer] interface {
+ M()
+}
+
+type Qer interface {
+ Q()
+}
+
+type F[A, B any] struct{}
+
+func (f *F[A, B]) Q() {}
// underIs calls f with the underlying types of the specific type terms
// of s and reports whether all calls to f returned true. If there are
-// no specific terms, is returns the result of f(nil).
+// no specific terms, underIs returns the result of f(nil).
func (s *_TypeSet) underIs(f func(Type) bool) bool {
if !s.hasTerms() {
return f(nil)