Skip to content

Commit 938e96e

Browse files
[dev.go2go] go/go2go: instantiate embedded field when needed
If an embedded field is an instantiated type, we need to instantiate it when instantiating the whole type, in case the type arguments themselves need instantiation. Fixes #39953 Change-Id: I80b57456aa4f8e8b2eff82359066c37a9c2a40f5 Reviewed-on: https://go-review.googlesource.com/c/go/+/240522 Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 08b9fd1 commit 938e96e

File tree

3 files changed

+50
-2
lines changed

3 files changed

+50
-2
lines changed

src/go/go2go/instantiate.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,22 @@ func (t *translator) instantiateExpr(ta *typeArgs, e ast.Expr) ast.Expr {
676676
}
677677
case *ast.SelectorExpr:
678678
x := t.instantiateExpr(ta, e.X)
679-
if x == e.X {
679+
680+
// If this is a reference to an instantiated embedded field,
681+
// we may need to instantiate it. The actual instantiation
682+
// is at the end of the function, as long as we create a
683+
// a new SelectorExpr when needed.
684+
instantiate := false
685+
obj := t.importer.info.ObjectOf(e.Sel)
686+
if obj != nil {
687+
if f, ok := obj.(*types.Var); ok && f.Embedded() {
688+
if named, ok := f.Type().(*types.Named); ok && len(named.TArgs()) > 0 && obj.Name() == named.Obj().Name() {
689+
instantiate = true
690+
}
691+
}
692+
}
693+
694+
if x == e.X && !instantiate {
680695
return e
681696
}
682697
r = &ast.SelectorExpr{

src/go/go2go/rewrite.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,11 @@ func (t *translator) translateSelectorExpr(pe *ast.Expr) {
794794
// We have to rewrite the name to the name used in
795795
// the translated struct definition.
796796
if f, ok := obj.(*types.Var); ok && f.Embedded() {
797-
named, ok := f.Type().(*types.Named)
797+
typ := t.lookupType(e)
798+
if typ == nil {
799+
typ = f.Type()
800+
}
801+
named, ok := typ.(*types.Named)
798802
if !ok || len(named.TArgs()) == 0 {
799803
return
800804
}

test/gen/g039.go2

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// compile
2+
3+
// Copyright 2020 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 p
8+
9+
type top(type T, T2) struct {
10+
p *parent(T, T2)
11+
}
12+
13+
type parent(type T, T2) struct {
14+
(child(T, T2))
15+
}
16+
17+
type child(type T, T2) struct {
18+
T2
19+
}
20+
21+
func (d *top(T, T2)) foo() *T {
22+
return d.p.child.foo()
23+
}
24+
25+
func (rb *child(T, T2)) foo() *T {
26+
return nil
27+
}
28+
29+
var V top(int, int)

0 commit comments

Comments
 (0)