From edb963e7e908535cfc9a9456609d87487f7ffd3c Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 18 Dec 2019 22:10:28 -0800 Subject: [PATCH] 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 --- src/go/types/call.go | 4 +--- src/go/types/predicates.go | 4 ++-- src/go/types/subst.go | 1 + src/go/types/testdata/linalg.go2 | 12 ++++-------- src/go/types/testdata/tmp.go2 | 6 +++--- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/go/types/call.go b/src/go/types/call.go index f6b942da67..84bf6026f5 100644 --- a/src/go/types/call.go +++ b/src/go/types/call.go @@ -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] { diff --git a/src/go/types/predicates.go b/src/go/types/predicates.go index 22d2a5c8cd..c7491a31f4 100644 --- a/src/go/types/predicates.go +++ b/src/go/types/predicates.go @@ -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 } diff --git a/src/go/types/subst.go b/src/go/types/subst.go index e3ca4d3ab1..2c11799987 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -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) diff --git a/src/go/types/testdata/linalg.go2 b/src/go/types/testdata/linalg.go2 index 1b44cfd5d1..55c671a8ce 100644 --- a/src/go/types/testdata/linalg.go2 +++ b/src/go/types/testdata/linalg.go2 @@ -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))) } diff --git a/src/go/types/testdata/tmp.go2 b/src/go/types/testdata/tmp.go2 index 24adce03fe..4ba882f949 100644 --- a/src/go/types/testdata/tmp.go2 +++ b/src/go/types/testdata/tmp.go2 @@ -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))()