diff --git a/src/go/types/NOTES b/src/go/types/NOTES index 2d4f163f3a..7752b1f138 100644 --- a/src/go/types/NOTES +++ b/src/go/types/NOTES @@ -5,7 +5,6 @@ so we have a better track record. I only switched to this file in Nov 2019, henc TODO - type assertions on/against parameterized types -- no need for error messages where a _ type parameter cannot be inferred (_ cannot be used) - use Underlying() to return a type parameter's bound? investigate! - if type parameters are repeated in recursive instantiation, they must be the same order (not yet checked) - debug (and error msg) printing of generic instantiated types needs some work @@ -13,12 +12,17 @@ TODO - use []*TypeParam for tparams in subst? (unclear) ---------------------------------------------------------------------------------------------------- -OPEN ISSUES +KNOWN ISSUES - instantiating a parameterized function type w/o value or result parameters may have unexpected side-effects (we don't make a copy of the signature in some cases) - investigate -- using a contract and enumerating type arguments currently leads to an error (e.g. func f(type T C(T)) (x T) ... ) +- using a contract and providing type arguments currently leads to an error (e.g. func f(type T C(T)) (x T) ... ) - leaving away unused receiver type parameters leads to an error; e.g.: "type S(type T) struct{}; func (S) _()" +- using _ for an unused receiver type parameter leads to an error and crash; e.g.: "type T(type P) int; func (_ T(_)) m()" + +---------------------------------------------------------------------------------------------------- +OPEN QUESTIONS + - confirm that it's ok to use inference in missingMethod to compare parameterized methods - now that we allow parenthesized embedded interfaces, should we allow parenthesized embedded fields? (probably yes, for symmetry and consistency). diff --git a/src/go/types/resolver.go b/src/go/types/resolver.go index c20da1f66a..82948c6019 100644 --- a/src/go/types/resolver.go +++ b/src/go/types/resolver.go @@ -502,12 +502,13 @@ func (check *Checker) collectObjects() { // cannot easily work around). func (check *Checker) unpackRecv(rtyp ast.Expr, unpackParams bool) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) { L: // unpack receiver type + // This accepts invalid receivers such as ***T but we don't care. + // The validity of receiver expressions is checked elsewhere. for { switch t := rtyp.(type) { case *ast.ParenExpr: rtyp = t.X case *ast.StarExpr: - // TODO(gri) this is incorrect - we shouldn't permit say ***T as a receiver here rtyp = t.X default: break L diff --git a/src/go/types/testdata/tmp.go2 b/src/go/types/testdata/tmp.go2 index 4dc15e2279..3076e96ed2 100644 --- a/src/go/types/testdata/tmp.go2 +++ b/src/go/types/testdata/tmp.go2 @@ -27,8 +27,11 @@ type II interface{ var _ I = II(nil) */ +type T(type P) int + +func (_ T(P)) m() int + func _() { - contract /* ERROR "inside function" */ C() {} - contract /* ERROR "inside function" */ C(T) {} - contract /* ERROR "inside function" */ C(T) { C(T); T m(); T int } -} \ No newline at end of file + // var x T(int) + // _ = x.m() +} diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 84af3c039c..6bdcb7dd3c 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -176,6 +176,7 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast // - a receiver type parameter is like any other type parameter, except that it is passed implicitly (via the receiver) // - the receiver specification acts as local declaration for its type parameters (which may be blank _) // - if the receiver type is parameterized but we don't need the parameters, we permit leaving them away + // (TODO(gri) this is not working because the code doesn't allow an uninstantiated parameterized recv type) _, rname, rparams := check.unpackRecv(recvPar.List[0].Type, true) if len(rparams) > 0 { sig.rparams = check.declareTypeParams(nil, rparams, nil)