diff options
| author | Dan Scales <danscales@google.com> | 2021-12-15 18:42:00 -0800 |
|---|---|---|
| committer | Dan Scales <danscales@google.com> | 2022-01-04 22:05:15 +0000 |
| commit | e39ab9b01cbbdac0750fc13fa8fb1de4f07aa79a (patch) | |
| tree | c7e463a24424ee65f7a31acaca5bc51725508830 /src | |
| parent | 1c8f9d2c97db7390a7ed2cd4663571b544147f4d (diff) | |
| download | go-e39ab9b01cbbdac0750fc13fa8fb1de4f07aa79a.tar.xz | |
cmd/compile: pop instantiations of local types when leaving scope
Since we use existing instantiations from the symbol table when possible
(to make sure each instantiation is unique), we need to pop
instantiations of local types when leaving the containing scope.
g.stmts() now pushes and pops scope, and we do a Pushdcl() in g.typ0()
when creating an instantiation of a local type.
Non-instantiated local types (generic or not) are translated directly
from types2, so they don't need to be pushed/popped. We don't export
function bodies with local types, so there is no issue during import.
We still don't support local types in generic functions/methods.
Fixes #50177
Change-Id: If2d2fe71aec003d13f0338565c7a0da2c9580a14
Reviewed-on: https://go-review.googlesource.com/c/go/+/372654
Reviewed-by: Keith Randall <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/noder/stmt.go | 3 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/types.go | 9 |
2 files changed, 11 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/noder/stmt.go b/src/cmd/compile/internal/noder/stmt.go index 1e996b95c4..a349a7ef10 100644 --- a/src/cmd/compile/internal/noder/stmt.go +++ b/src/cmd/compile/internal/noder/stmt.go @@ -13,8 +13,10 @@ import ( "cmd/internal/src" ) +// stmts creates nodes for a slice of statements that form a scope. func (g *irgen) stmts(stmts []syntax.Stmt) []ir.Node { var nodes []ir.Node + types.Markdcl() for _, stmt := range stmts { switch s := g.stmt(stmt).(type) { case nil: // EmptyStmt @@ -24,6 +26,7 @@ func (g *irgen) stmts(stmts []syntax.Stmt) []ir.Node { nodes = append(nodes, s) } } + types.Popdcl() return nodes } diff --git a/src/cmd/compile/internal/noder/types.go b/src/cmd/compile/internal/noder/types.go index 4f6d828720..ed816b4955 100644 --- a/src/cmd/compile/internal/noder/types.go +++ b/src/cmd/compile/internal/noder/types.go @@ -123,7 +123,14 @@ func (g *irgen) typ0(typ types2.Type) *types.Type { // Make sure the base generic type exists in type1 (it may // not yet if we are referecing an imported generic type, as // opposed to a generic type declared in this package). - _ = g.obj(typ.Origin().Obj()) + base := g.obj(typ.Origin().Obj()) + if base.Class == ir.PAUTO { + // If the base type is a local type, we want to pop + // this instantiated type symbol/definition when we + // leave the containing block, so we don't use it + // incorrectly later. + types.Pushdcl(s) + } // Create a forwarding type first and put it in the g.typs // map, in order to deal with recursive generic types |
