1
0
mirror of https://github.com/golang/go synced 2024-11-17 08:54:41 -07:00

go/types, types2: use Identical rather than unification in missingMethod

Now that we instantiate methods on instantiated types, there is no need
to use unification to match signatures inside of missingMethod.

Generally, we should never encounter uninstantiated signatures within
statements. If we do encounter signatures that contain type parameters,
it is because the signatures are themselves defined or instantiated
using type parameters declared in the function scope (see example
below). The current unification logic would not handle this.

	type S[T any] struct{}
	func (S[T]) m(T)

	func _[P any]() bool {
		var v interface{m(int)}
		_, ok = v.(S[P])
		return ok
	}

Change-Id: I754fb5535bba2fc7a209dc7419fd4015c413c9a6
Reviewed-on: https://go-review.googlesource.com/c/go/+/379540
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Robert Findley 2022-01-19 22:00:42 -05:00
parent e7d5857a5a
commit 9284279b44
2 changed files with 4 additions and 45 deletions

View File

@ -328,14 +328,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
panic("method with type parameters")
}
// If the methods have type parameters we don't care whether they
// are the same or not, as long as they match up. Use unification
// to see if they can be made to match.
// TODO(gri) is this always correct? what about type bounds?
// (Alternative is to rename/subst type parameters and compare.)
u := newUnifier(true)
u.x.init(ftyp.TypeParams().list())
if !u.unify(ftyp, mtyp) {
if !Identical(ftyp, mtyp) {
return m, f
}
}
@ -388,27 +381,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
panic("method with type parameters")
}
// If the methods have type parameters we don't care whether they
// are the same or not, as long as they match up. Use unification
// to see if they can be made to match.
// TODO(gri) is this always correct? what about type bounds?
// (Alternative is to rename/subst type parameters and compare.)
u := newUnifier(true)
if ftyp.TypeParams().Len() > 0 {
// We reach here only if we accept method type parameters.
// In this case, unification must consider any receiver
// and method type parameters as "free" type parameters.
assert(acceptMethodTypeParams)
// We don't have a test case for this at the moment since
// we can't parse method type parameters. Keeping the
// unimplemented call so that we test this code if we
// enable method type parameters.
unimplemented()
u.x.init(append(ftyp.RecvTypeParams().list(), ftyp.TypeParams().list()...))
} else {
u.x.init(ftyp.RecvTypeParams().list())
}
if !u.unify(ftyp, mtyp) {
if !Identical(ftyp, mtyp) {
return m, f
}
}

View File

@ -320,14 +320,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
panic("method with type parameters")
}
// If the methods have type parameters we don't care whether they
// are the same or not, as long as they match up. Use unification
// to see if they can be made to match.
// TODO(gri) is this always correct? what about type bounds?
// (Alternative is to rename/subst type parameters and compare.)
u := newUnifier(true)
u.x.init(ftyp.TypeParams().list())
if !u.unify(ftyp, mtyp) {
if !Identical(ftyp, mtyp) {
return m, f
}
}
@ -375,14 +368,7 @@ func (check *Checker) missingMethod(V Type, T *Interface, static bool) (method,
panic("method with type parameters")
}
// If the methods have type parameters we don't care whether they
// are the same or not, as long as they match up. Use unification
// to see if they can be made to match.
// TODO(gri) is this always correct? what about type bounds?
// (Alternative is to rename/subst type parameters and compare.)
u := newUnifier(true)
u.x.init(ftyp.RecvTypeParams().list())
if !u.unify(ftyp, mtyp) {
if !Identical(ftyp, mtyp) {
return m, f
}
}