go/types: fixed testdata/linalg.go2 example

The new lazy method substitution code seems to work. The bug was
in the test, not in the implementation!

Change-Id: I39794743a01e9725d57f49ccd7c3751376cd01d6
This commit is contained in:
Robert Griesemer 2019-12-18 22:10:28 -08:00
parent a28b69c5d0
commit edb963e7e9
5 changed files with 11 additions and 16 deletions

View File

@ -26,9 +26,7 @@ func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
// conversion or type instantiation
T := x.typ
x.mode = invalid
// A parameterized type is only instantiated if it doesn't have an instantiation already (see named.targs).
// TODO(gri) This seems a bit subtle. Can we do better?
if named, _ := T.(*Named); named != nil && named.obj != nil && named.obj.IsParameterized() && named.targs == nil {
if isGeneric(T) {
// type instantiation
x.typ = check.typ(e)
if x.typ != Typ[Invalid] {

View File

@ -19,9 +19,9 @@ func isNamed(typ Type) bool {
return ok
}
// isGeneric reports whether a type is a generic, uninstantiated type
// (generic signatures are not included).
// isGeneric reports whether a type is a generic, uninstantiated type (generic signatures are not included).
func isGeneric(typ Type) bool {
// A parameterized type is only instantiated if it doesn't have an instantiation already.
named, _ := typ.(*Named)
return named != nil && named.obj != nil && named.obj.IsParameterized() && named.targs == nil
}

View File

@ -83,6 +83,7 @@ func (check *Checker) instantiate(pos token.Pos, typ Type, targs []Type, poslist
iface = check.subst(pos, iface, tparams, targs).(*Interface)
// update targ method signatures
// TODO(gri) This needs documentation and cleanups!
update := func(V Type, sig *Signature) *Signature {
V, _ = deref(V)
// check.dump(">>> %s: V = %s", pos, V)

View File

@ -61,7 +61,7 @@ contract Complex(T) {
// ordered numeric types.
type OrderedAbs(type T OrderedNumeric) T
func (a OrderedAbs(T)) Abs() T {
func (a OrderedAbs(T)) Abs() OrderedAbs(T) {
if a < 0 {
return -a
}
@ -72,7 +72,7 @@ func (a OrderedAbs(T)) Abs() T {
// complex types.
type ComplexAbs(type T Complex) T
func (a ComplexAbs(T)) Abs() T {
func (a ComplexAbs(T)) Abs() ComplexAbs(T) {
r := float64(real(a))
i := float64(imag(a))
d := math.Sqrt(r * r + i * i)
@ -80,13 +80,9 @@ func (a ComplexAbs(T)) Abs() T {
}
func OrderedAbsDifference(type T OrderedNumeric)(a, b T) T {
// TODO(gri) fix this
// return T(AbsDifference(OrderedAbs(T)(a), OrderedAbs(T)(b)))
return a
return T(AbsDifference(OrderedAbs(T)(a), OrderedAbs(T)(b)))
}
func ComplexAbsDifference(type T Complex)(a, b T) T {
// TODO(gri) fix this
// return T(AbsDifference(ComplexAbs(T)(a), ComplexAbs(T)(b)))
return a
return T(AbsDifference(ComplexAbs(T)(a), ComplexAbs(T)(b)))
}

View File

@ -8,10 +8,10 @@ func f(type P interface{ m() P })(x P)
type T(type P) P
func (_ T(P)) m() P
func (_ T(P)) m() T(P)
func _(type Q)(x Q) {
f(T /* ERROR does not satisfy */ (Q))(T(Q)(x))
f(T(Q))(T(Q)(x))
}
// TODO(gri) Once the code above works, check the code below.
@ -24,7 +24,7 @@ func AbsDifference(type T NumericAbs(T))()
type OrderedAbs(type T) T
func (a OrderedAbs(T)) Abs() T
func (a OrderedAbs(T)) Abs() OrderedAbs(T)
func OrderedAbsDifference(type T)() {
AbsDifference(OrderedAbs(T))()