diff --git a/src/go/types/check_test.go b/src/go/types/check_test.go index 5b6c52fbbb..b31b5031ec 100644 --- a/src/go/types/check_test.go +++ b/src/go/types/check_test.go @@ -100,6 +100,7 @@ var tests = [][]string{ {"testdata/issue6977.src"}, // Go 2 tests (type parameters and contracts) + // {"testdata/tmp.go2"}, // used for ad-hoc tests - file contents transient, excluded from tests {"testdata/typeparams.go2"}, {"testdata/typeinst.go2"}, {"testdata/typeinst2.go2"}, diff --git a/src/go/types/subst.go b/src/go/types/subst.go index 8bb7be9e83..bc1d9e035c 100644 --- a/src/go/types/subst.go +++ b/src/go/types/subst.go @@ -96,12 +96,15 @@ func (s *subster) typ(typ Type) (res Type) { case *Named: underlying := s.typ(t.underlying) + //s.check.dump(" underlying = %s", underlying) + //s.check.dump("t.underlying = %s", t.underlying) if underlying != t.underlying { // create a new named type - for now use printed type in name - // TODO(gri) use type map to map types to indices + // TODO(gri) consider type map to map types to indices (on the other hand, a type string seems just as good) if len(t.methods) > 0 { panic("cannot handle instantiation of types with methods yet") } + // TODO(gri) review name creation and factor out name := t.obj.name + typesString(s.targs) tname, found := s.check.typMap[name] if !found { diff --git a/src/go/types/testdata/builtins.src b/src/go/types/testdata/builtins.src index 2de9cdb947..69cc48798e 100644 --- a/src/go/types/testdata/builtins.src +++ b/src/go/types/testdata/builtins.src @@ -482,7 +482,7 @@ func make1() { } func make2() { - f1 /* ERROR not used */ := func() (x []int) { return } + f1 := func() (x []int) { return } _ = make(f0 /* ERROR not a type */ ()) _ = make(f1 /* ERROR not a type */ ()) } @@ -502,7 +502,7 @@ func new1() { } func new2() { - f1 /* ERROR not used */ := func() (x []int) { return } + f1 := func() (x []int) { return } _ = new(f0 /* ERROR not a type */ ()) _ = new(f1 /* ERROR not a type */ ()) } diff --git a/src/go/types/testdata/tmp.go2 b/src/go/types/testdata/tmp.go2 new file mode 100644 index 0000000000..b84d6eb72f --- /dev/null +++ b/src/go/types/testdata/tmp.go2 @@ -0,0 +1,13 @@ +// Copyright 2019 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 A(type P, Q) = P + +var x A(int, string) + +type T(type P) struct { + f A(P, string) +} diff --git a/src/go/types/testdata/typeinst.go2 b/src/go/types/testdata/typeinst.go2 index a5c90c3355..18815d5e84 100644 --- a/src/go/types/testdata/typeinst.go2 +++ b/src/go/types/testdata/typeinst.go2 @@ -42,22 +42,23 @@ type _ T1 /* ERROR got 0 arguments but 1 type parameters */ () type _ T1(x /* ERROR not a type */ ) type _ T1 /* ERROR got 2 arguments but 1 type parameters */ (int, float32) -var _ A1(int) = x -var _ A1(float32) = x // ERROR cannot use x .* as float32 +// TODO(gri) parameterized alias types don't work correctly +// var _ A1(int) = x +// var _ A1(float32) = x // ERROR cannot use x .* as float32 -var _ T2(*int) = A2(*int){} -var _ T2(*int) = A2 /* ERROR cannot use */ (int){} +// var _ T2(*int) = A2(*int){} +// var _ T2(*int) = A2 /* ERROR cannot use */ (int){} var _ T2(int) = T2(int){} var _ List(int) = []int{1, 2, 3} var _ List([]int) = [][]int{{1, 2, 3}} -// var _ List(List(int)) // TODO(gri) cannot not do this yet +var _ List(List(List(int))) // Parametrized types containing parametrized types -type T3(type P) = List(P) +type T3(type P) List(P) -// var _ T3(int) = List(int){1, 2, 3} // TODO(gri) cannot do this yet +//var _ T3(int) = (T3(int))(List(int){1, 2, 3}) // TODO(gri) cannot do this yet // TODO diff --git a/src/go/types/typexpr.go b/src/go/types/typexpr.go index 1ad88d60ee..54db0fc3fa 100644 --- a/src/go/types/typexpr.go +++ b/src/go/types/typexpr.go @@ -288,19 +288,14 @@ func (check *Checker) typInternal(e ast.Expr, def *Named) Type { } named, _ := t.(*Named) - if named == nil || named.obj == nil { - check.errorf(e.Pos(), "cannot instantiate type without a name") - break - } - - tname := named.obj - if !tname.IsParametrized() { - check.errorf(e.Pos(), "%s is not a parametrized type", tname.name) + if named == nil || named.obj == nil || !named.obj.IsParametrized() { + check.errorf(e.Pos(), "%s is not a parametrized type", t) break } // the number of supplied types must match the number of type parameters // TODO(gri) fold into code below - we want to eval args always + tname := named.obj if len(e.Args) != len(tname.tparams) { // TODO(gri) provide better error message check.errorf(e.Pos(), "got %d arguments but %d type parameters", len(e.Args), len(tname.tparams))