diff options
| author | Alan Donovan <adonovan@google.com> | 2025-09-18 14:04:43 -0400 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-09-23 13:12:12 -0700 |
| commit | 7bc1935db55c9d182617aba074f048f9c7573680 (patch) | |
| tree | 042fbd7352c4a890a43f19d214b00d4bbc26b19f /src/cmd/compile/internal/noder | |
| parent | eb78f13c9f195ba11fd9518257b6e45997b14de5 (diff) | |
| download | go-7bc1935db55c9d182617aba074f048f9c7573680.tar.xz | |
cmd/compile/internal: support new(expr)
This CL adds compiler support for new(expr),
a feature of go1.26 that allows the user to specify
the initial value of the variable instead of its
type.
Also, a basic test of dynamic behavior.
See CL 704737 for spec change and CL 704935 for
type-checker changes.
For #45624
Change-Id: I65d27de1ee3aabb819b57cce8ea77f3073447757
Reviewed-on: https://go-review.googlesource.com/c/go/+/705157
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Mateusz Poliwczak <mpoliwczak34@gmail.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder')
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 13 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/writer.go | 8 |
2 files changed, 18 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 45e2bfd727..ca7c6bf151 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -2431,8 +2431,16 @@ func (r *reader) expr() (res ir.Node) { case exprNew: pos := r.pos() - typ := r.exprType() - return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ)) + if r.Bool() { + // new(expr) -> tmp := expr; &tmp + x := r.expr() + var init ir.Nodes + addr := ir.NewAddrExpr(pos, r.tempCopy(pos, x, &init)) + addr.SetInit(init) + return typecheck.Expr(addr) + } + // new(T) + return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, r.exprType())) case exprSizeof: return ir.NewUintptr(r.pos(), r.typ().Size()) @@ -3239,6 +3247,7 @@ func (r *reader) exprType() ir.Node { var rtype, itab ir.Node if r.Bool() { + // non-empty interface typ, rtype, _, _, itab = r.itab(pos) if !typ.IsInterface() { rtype = nil // TODO(mdempsky): Leave set? diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index 54e5f1ea5f..9c90d221c2 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -2035,10 +2035,16 @@ func (w *writer) expr(expr syntax.Expr) { case "new": assert(len(expr.ArgList) == 1) assert(!expr.HasDots) + arg := expr.ArgList[0] w.Code(exprNew) w.pos(expr) - w.exprType(nil, expr.ArgList[0]) + tv := w.p.typeAndValue(arg) + if w.Bool(!tv.IsType()) { + w.expr(arg) // new(expr), go1.26 + } else { + w.exprType(nil, arg) // new(T) + } return case "Sizeof": |
