aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlan Donovan <adonovan@google.com>2025-09-17 22:17:41 -0400
committerAlan Donovan <adonovan@google.com>2025-09-23 11:36:46 -0700
commita27261c42fcebf601587725714b9ef53c47b06b3 (patch)
tree2f584ab21e11369633139c3c8f5752779a68bafa /src
parente93f439ac4160baf9992f059d2bfb511e23f63c9 (diff)
downloadgo-a27261c42fcebf601587725714b9ef53c47b06b3.tar.xz
go/types,types2: allow new(expr)
For #45624 Change-Id: I6d77a2a1d6095cac0edc36060cbf98c72b749404 Reviewed-on: https://go-review.googlesource.com/c/go/+/704935 Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/builtins.go27
-rw-r--r--src/cmd/compile/internal/types2/version.go1
-rw-r--r--src/go/types/builtins.go27
-rw-r--r--src/go/types/version.go1
-rw-r--r--src/internal/types/testdata/check/builtins0.go46
-rw-r--r--src/internal/types/testdata/check/go1_25.go13
-rw-r--r--src/internal/types/testdata/fixedbugs/issue43125.go8
7 files changed, 96 insertions, 27 deletions
diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go
index 4bb2135755..3de2857ed4 100644
--- a/src/cmd/compile/internal/types2/builtins.go
+++ b/src/cmd/compile/internal/types2/builtins.go
@@ -636,11 +636,30 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) (
}
case _New:
- // new(T)
+ // new(T) or new(expr)
// (no argument evaluated yet)
- T := check.varType(argList[0])
- if !isValid(T) {
- return
+ arg := argList[0]
+ check.exprOrType(x, arg, true)
+ var T Type
+ switch x.mode {
+ case builtin:
+ check.errorf(x, UncalledBuiltin, "%s must be called", x)
+ x.mode = invalid
+ case typexpr:
+ // new(T)
+ T = x.typ
+ if !isValid(T) {
+ return
+ }
+ default:
+ // new(expr)
+ check.verifyVersionf(call.Fun, go1_26, "new(expr)")
+ T = Default(x.typ)
+ if T != x.typ {
+ // untyped constant: check for overflow.
+ check.assignment(x, T, "argument to new")
+ }
+ check.validVarType(arg, T)
}
x.mode = value
diff --git a/src/cmd/compile/internal/types2/version.go b/src/cmd/compile/internal/types2/version.go
index b555f398da..765b0f7e9a 100644
--- a/src/cmd/compile/internal/types2/version.go
+++ b/src/cmd/compile/internal/types2/version.go
@@ -43,6 +43,7 @@ var (
go1_21 = asGoVersion("go1.21")
go1_22 = asGoVersion("go1.22")
go1_23 = asGoVersion("go1.23")
+ go1_26 = asGoVersion("go1.26")
// current (deployed) Go version
go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version))
diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go
index e9f2b3e21d..1163321ecd 100644
--- a/src/go/types/builtins.go
+++ b/src/go/types/builtins.go
@@ -639,11 +639,30 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
}
case _New:
- // new(T)
+ // new(T) or new(expr)
// (no argument evaluated yet)
- T := check.varType(argList[0])
- if !isValid(T) {
- return
+ arg := argList[0]
+ check.exprOrType(x, arg, true)
+ var T Type
+ switch x.mode {
+ case builtin:
+ check.errorf(x, UncalledBuiltin, "%s must be called", x)
+ x.mode = invalid
+ case typexpr:
+ // new(T)
+ T = x.typ
+ if !isValid(T) {
+ return
+ }
+ default:
+ // new(expr)
+ check.verifyVersionf(call.Fun, go1_26, "new(expr)")
+ T = Default(x.typ)
+ if T != x.typ {
+ // untyped constant: check for overflow.
+ check.assignment(x, T, "argument to new")
+ }
+ check.validVarType(arg, T)
}
x.mode = value
diff --git a/src/go/types/version.go b/src/go/types/version.go
index 2a2d341205..8133110398 100644
--- a/src/go/types/version.go
+++ b/src/go/types/version.go
@@ -43,6 +43,7 @@ var (
go1_21 = asGoVersion("go1.21")
go1_22 = asGoVersion("go1.22")
go1_23 = asGoVersion("go1.23")
+ go1_26 = asGoVersion("go1.26")
// current (deployed) Go version
go_current = asGoVersion(fmt.Sprintf("go1.%d", goversion.Version))
diff --git a/src/internal/types/testdata/check/builtins0.go b/src/internal/types/testdata/check/builtins0.go
index ea30fbcbe7..e326b92ac7 100644
--- a/src/internal/types/testdata/check/builtins0.go
+++ b/src/internal/types/testdata/check/builtins0.go
@@ -609,24 +609,48 @@ func min2() {
)
}
-func new1() {
- _ = new() // ERROR "not enough arguments"
+func newInvalid() {
+ f2 := func() (x, y int) { return }
+
+ _ = new() // ERROR "not enough arguments"
_ = new(1, 2) // ERROR "too many arguments"
- _ = new("foo" /* ERROR "not a type" */)
- p := new(float64)
+ new /* ERROR "not used" */ (int)
+ _ = &new /* ERROR "cannot take address" */ (int)
+ _ = new(int... /* ERROR "invalid use of ..." */)
+ _ = new(f0 /* ERROR "f0() (no value) used as value or type" */ ())
+ _ = new(len /* ERROR "len (built-in) must be called" */)
+ _ = new(1 /* ERROR "argument to new (overflows)" */ << 70)
+ _ = new(f2 /* ERRORx "multiple-value.*in single-value context" */ ())
+}
+
+// new(T)
+func newType() {
_ = new(struct{ x, y int })
+
+ p := new(float64)
q := new(*float64)
_ = *p == **q
- new /* ERROR "not used" */ (int)
- _ = &new /* ERROR "cannot take address" */ (int)
-
- _ = new(int... /* ERROR "invalid use of ..." */ )
}
-func new2() {
+// new(expr), added in go1.26
+func newExpr() {
f1 := func() (x []int) { return }
- _ = new(f0 /* ERROR "not a type" */ ())
- _ = new(f1 /* ERROR "not a type" */ ())
+ var (
+ _ *[]int = new(f1())
+ _ *func() []int = new(f1)
+ _ *bool = new(false)
+ _ *int = new(123)
+ _ *float64 = new(1.0)
+ _ *uint = new(uint(3))
+ _ *rune = new('a')
+ _ *string = new("A")
+ _ *struct{} = new(struct{}{})
+ _ *any = new(any)
+
+ // from issue 43125
+ _ = new(-1)
+ _ = new(1 + 1)
+ )
}
func panic1() {
diff --git a/src/internal/types/testdata/check/go1_25.go b/src/internal/types/testdata/check/go1_25.go
new file mode 100644
index 0000000000..b2ace83343
--- /dev/null
+++ b/src/internal/types/testdata/check/go1_25.go
@@ -0,0 +1,13 @@
+// -lang=go1.25
+
+// 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.
+
+// Check Go language version-specific errors.
+
+//go:build go1.25
+
+package p
+
+var _ = new /* ERROR "new(expr) requires go1.26 or later" */ (123)
diff --git a/src/internal/types/testdata/fixedbugs/issue43125.go b/src/internal/types/testdata/fixedbugs/issue43125.go
deleted file mode 100644
index d0d6feb2a8..0000000000
--- a/src/internal/types/testdata/fixedbugs/issue43125.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2021 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 p
-
-var _ = new(- /* ERROR "not a type" */ 1)
-var _ = new(1 /* ERROR "not a type" */ + 1)