ORSH // X >> Y
OAND // X & Y
OANDNOT // X &^ Y
- ONEW // new(X); corresponds to calls to new in source code
+ ONEW // new(X); corresponds to calls to new(T) in source code
ONOT // !X
OBITNOT // ^X
OPLUS // +X
// A DynamicType represents a type expression whose exact type must be
// computed dynamically.
+//
+// TODO(adonovan): I think "dynamic" is a misnomer here; it's really a
+// type with free type parameters that needs to be instantiated to obtain
+// a ground type for which an rtype can exist.
type DynamicType struct {
miniExpr
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())
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?
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":
--- /dev/null
+// run
+
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+// Issue #45624 is the proposal to accept new(expr) in go1.26.
+// Here we test its run-time behavior.
+func main() {
+ {
+ p := new(123) // untyped constant expr
+ if *p != 123 {
+ panic("wrong value")
+ }
+ }
+ {
+ x := 42
+ p := new(x) // non-constant expr
+ if *p != x {
+ panic("wrong value")
+ }
+ }
+ {
+ x := [2]int{123, 456}
+ p := new(x) // composite value
+ if *p != x {
+ panic("wrong value")
+ }
+ }
+}
_ = int // ERROR "type int is not an expression|not an expression"
(x) // ERROR "x .* not used|not used"
_ = new(len) // ERROR "len.*must be called"
- // Disabled due to issue #43125.
- // _ = new(1 + 1) // DISABLED "1 \+ 1 is not a type"
+ _ = new(1 + 1) // ok
}