Skip to content

Commit 560dc97

Browse files
committed
cmd/compile: error when using internal type declarations in generic functions
We hope to support this feature one day, but it doesn't work currently. Issue a nice error message instead of having the compiler crash. Update #47631 Change-Id: I0359411410acbaf9a5b9dbb988cd933de1bb8438 Reviewed-on: https://go-review.googlesource.com/c/go/+/364054 Trust: Keith Randall <[email protected]> Trust: Dan Scales <[email protected]> Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Dan Scales <[email protected]>
1 parent 9265558 commit 560dc97

File tree

5 files changed

+48
-7
lines changed

5 files changed

+48
-7
lines changed

src/cmd/compile/internal/noder/stmt.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ func (g *irgen) stmt(stmt syntax.Stmt) ir.Node {
4646
n.SetTypecheck(1)
4747
return n
4848
case *syntax.DeclStmt:
49+
if _, ok := stmt.DeclList[0].(*syntax.TypeDecl); ok && g.topFuncIsGeneric {
50+
// TODO: remove this restriction. See issue 47631.
51+
base.ErrorfAt(g.pos(stmt), "type declarations inside generic functions are not currently supported")
52+
}
4953
n := ir.NewBlockStmt(g.pos(stmt), nil)
5054
g.decls(&n.List, stmt.DeclList)
5155
return n

test/run.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2186,6 +2186,7 @@ var unifiedFailures = setOf(
21862186
"fixedbugs/issue42284.go", // prints "T(0) does not escape", but test expects "a.I(a.T(0)) does not escape"
21872187
"fixedbugs/issue7921.go", // prints "… escapes to heap", but test expects "string(…) escapes to heap"
21882188
"typeparam/issue48538.go", // assertion failure, interprets struct key as closure variable
2189+
"typeparam/issue47631.go", // unified IR can handle local type declarations
21892190
)
21902191

21912192
func setOf(keys ...string) map[string]bool {

test/typeparam/builtins.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,25 @@ func m1[
6969
C1 interface{ chan int },
7070
C2 interface{ chan int | chan string },
7171
]() {
72-
type S0 []int
7372
_ = make([]int, 10)
74-
_ = make(S0, 10)
73+
_ = make(m1S0, 10)
7574
_ = make(S1, 10)
7675
_ = make(S1, 10, 20)
7776

78-
type M0 map[string]int
7977
_ = make(map[string]int)
80-
_ = make(M0)
78+
_ = make(m1M0)
8179
_ = make(M1)
8280
_ = make(M1, 10)
8381

84-
type C0 chan int
8582
_ = make(chan int)
86-
_ = make(C0)
83+
_ = make(m1C0)
8784
_ = make(C1)
8885
_ = make(C1, 10)
8986
}
87+
// TODO: put these type declarations back inside m1 when issue 47631 is fixed.
88+
type m1S0 []int
89+
type m1M0 map[string]int
90+
type m1C0 chan int
9091

9192
// len/cap
9293

test/typeparam/issue47631.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// errorcheck -G=3
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// TODO: one day we will support internal type declarations, at which time this test will be removed.
8+
9+
package p
10+
11+
func g[T any]() {
12+
type U []T // ERROR "type declarations inside generic functions are not currently supported"
13+
type V []int // ERROR "type declarations inside generic functions are not currently supported"
14+
}
15+
16+
type S[T any] struct {
17+
}
18+
19+
func (s S[T]) m() {
20+
type U []T // ERROR "type declarations inside generic functions are not currently supported"
21+
type V []int // ERROR "type declarations inside generic functions are not currently supported"
22+
}
23+
24+
25+
func f() {
26+
type U []int // ok
27+
}
28+
29+
type X struct {
30+
}
31+
32+
func (x X) m() {
33+
type U []int // ok
34+
}

test/typeparam/typelist.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,12 @@ func at[T interface{ ~[]E }, E any](x T, i int) E {
2626
// type is itself, its "operational type" is defined by the type list in
2727
// the tybe bound, if any.
2828
func _[T interface{ ~int }](x T) {
29-
type myint int
3029
var _ int = int(x)
3130
var _ T = 42
3231
var _ T = T(myint(42))
3332
}
33+
// TODO: put this type declaration back inside the above function when issue 47631 is fixed.
34+
type myint int
3435

3536
// Indexing a generic type which has a structural contraints to be an array.
3637
func _[T interface{ ~[10]int }](x T) {

0 commit comments

Comments
 (0)