Skip to content

Commit b8c802b

Browse files
committed
cmd/compile: prevent importReader reading type parameter twice
The importReader always reads type parameter before declaring type stub declaration. Thus, for recursive type, the type parameter is going to be read twice, cause the bound more than once error. To fix this, only read the type parameter after declaring stub obj, thus r.doDecl can see the type was already inserted and terminate the recursive call earlier. Fixes #48280 Change-Id: I272e2f214f739fb8ec71a8628ba297477e1b7755 Reviewed-on: https://go-review.googlesource.com/c/go/+/349009 Trust: Cuong Manh Le <[email protected]> Trust: Dan Scales <[email protected]> Run-TryBot: Cuong Manh Le <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Dan Scales <[email protected]>
1 parent 4a4221e commit b8c802b

File tree

4 files changed

+35
-6
lines changed

4 files changed

+35
-6
lines changed

src/cmd/compile/internal/importer/iimport.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -318,17 +318,17 @@ func (r *importReader) obj(name string) {
318318
r.declare(types2.NewFunc(pos, r.currPkg, name, sig))
319319

320320
case 'T', 'U':
321-
var tparams []*types2.TypeParam
322-
if tag == 'U' {
323-
tparams = r.tparamList()
324-
}
325-
326321
// Types can be recursive. We need to setup a stub
327322
// declaration before recursing.
328323
obj := types2.NewTypeName(pos, r.currPkg, name, nil)
329324
named := types2.NewNamed(obj, nil, nil)
330-
named.SetTypeParams(tparams)
325+
// Declare obj before calling r.tparamList, so the new type name is recognized
326+
// if used in the constraint of one of its own typeparams (see #48280).
331327
r.declare(obj)
328+
if tag == 'U' {
329+
tparams := r.tparamList()
330+
named.SetTypeParams(tparams)
331+
}
332332

333333
underlying := r.p.typAt(r.uint64(), named).Underlying()
334334
named.SetUnderlying(underlying)

test/typeparam/issue48280.dir/a.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package a
6+
7+
type I[T I[T]] interface {
8+
F() T
9+
}
10+
11+
type S struct{}

test/typeparam/issue48280.dir/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright 2021 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import "a"
8+
9+
func main() {
10+
_ = a.S{}
11+
}

test/typeparam/issue48280.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rundir -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+
package ignored

0 commit comments

Comments
 (0)