From ef06a5f44a46dfaf601ca79717ffb00b3591d297 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Mart=C3=AD?=
-A numeric type represents sets of integer or floating-point values.
+An integer, floating-point, or complex type
+represents the set of integer, floating-point, or complex values, respectively.
+They are collectively called numeric types.
The predeclared architecture-independent numeric types are:
Numeric types
-There is also a set of predeclared numeric types with implementation-specific sizes: +There is also a set of predeclared integer types with implementation-specific sizes:
@@ -1921,7 +1923,7 @@ if one of the following conditions applies:
T is a floating-point type and x can be rounded to T's
+T is a floating-point type and x can be rounded to T's
precision without overflow. Rounding uses IEEE 754 round-to-even rules but with an IEEE
negative zero further simplified to an unsigned zero. Note that constant values never result
in an IEEE negative zero, NaN, or infinity.
@@ -3108,7 +3110,7 @@ For array and slice literals the following rules apply:
key must be a non-negative constant
representable by
a value of type int; and if it is typed
- it must be of integer type.
+ it must be of integer type.
a is not a map:
x must be of integer type or an untyped constantx must be of integer type or an untyped constantintint
-The right operand in a shift expression must have integer type
+The right operand in a shift expression must have integer type
or be an untyped constant representable by a
value of type uint.
If the left operand of a non-constant shift expression is an untyped constant,
@@ -4740,8 +4742,9 @@ x == y+1 && <-chanInt > 0
Arithmetic operators apply to numeric values and yield a result of the same
type as the first operand. The four standard arithmetic operators (+,
--, *, /) apply to integer,
-floating-point, and complex types; + also applies to strings.
+-, *, /) apply to
+integer, floating-point, and
+complex types; + also applies to strings
@@ -4880,7 +4883,7 @@ occurs is implementation-specific.
An implementation may combine multiple floating-point operations into a single
fused operation, possibly across statements, and produce a result that differs
from the value obtained by executing and rounding the instructions individually.
-An explicit floating-point type conversion rounds to
+An explicit floating-point type conversion rounds to
the precision of the target type, preventing fusion that would discard that rounding.
v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0.
The conversion always yields a valid value; there is no indication of overflow.
x of type float32
may be stored using additional precision beyond that of an IEEE-754 32-bit number,
@@ -7037,7 +7040,7 @@ make(T, n) channel buffered channel of type T, buffer size n
-Each of the size arguments n and m must be of integer type
+Each of the size arguments n and m must be of integer type
or an untyped constant.
A constant size argument must be non-negative and representable
by a value of type int; if it is an untyped constant it is given type int.
@@ -7182,7 +7185,8 @@ imag(complexT) floatT
The type of the arguments and return value correspond.
For complex, the two arguments must be of the same
-floating-point type and the return type is the complex type
+floating-point type and the return type is the
+complex type
with the corresponding floating-point constituents:
complex64 for float32 arguments, and
complex128 for float64 arguments.
@@ -7897,7 +7901,7 @@ of constant size.
The function Add adds len to ptr
and returns the updated pointer unsafe.Pointer(uintptr(ptr) + uintptr(len)).
-The len argument must be of integer type or an untyped constant.
+The len argument must be of integer type or an untyped constant.
A constant len argument must be representable by a value of type int;
if it is an untyped constant it is given type int.
The rules for valid uses of Pointer still apply.
@@ -7920,7 +7924,7 @@ is nil and len is zero,
-The len argument must be of integer type or an untyped constant.
+The len argument must be of integer type or an untyped constant.
A constant len argument must be non-negative and representable by a value of type int;
if it is an untyped constant it is given type int.
At run time, if len is negative,
From 540632841e678573885e296db0cb73b15f48f96c Mon Sep 17 00:00:00 2001
From: Ian Lance Taylor
+ The predicates
+ AssignableTo,
+ ConvertibleTo,
+ Implements,
+ Identical,
+ IdenticalIgnoreTags, and
+ AssertableTo
+ now also work with arguments that are or contain generalized interfaces, i.e. interfaces
+ that may only be used as type constraints in Go code.
+ Note that the behavior of AssertableTo is undefined if the first argument
+ is a generalized interface.
+
+ TODO: https://golang.org/cl/353969: enable register ABI for PPC64 +
+-fsanitize=address).
-+
The go mod tidy command now retains
additional checksums in the go.sum file for modules whose source
code is needed to verify that each imported package is provided by only one
@@ -376,6 +382,10 @@ Do not send CLs removing the interior tags from such phrases.
+ TODO: https://golang.org/cl/240611: 240611: cmd/fix: add buildtag fix +
+gofmt
@@ -506,6 +516,12 @@ Do not send CLs removing the interior tags from such phrases.
new go command -asan option.
+ TODO: https://golang.org/cl/369914: for default bootstrap, use Go 1.17 if present, falling back to Go 1.4 +
+debug/buildinfo package+ TODO: https://golang.org/cl/321889: allocate hiter as part of MapIter +
+ ++ TODO: https://golang.org/cl/345486: optimize for maps with string keys +
From 9ed0d81fb5b2a7e6707010a226b72626433b83d2 Mon Sep 17 00:00:00 2001 From: Eric Lagergren
-An interface T is called structural if one of the following
+An interface T has a core type if one of the following
conditions is satisfied:
-A structural interface has a structural type which is, depending on the -condition that is satisfied, either: +All other interfaces don't have a core type. +
+ ++The core type is, depending on the condition that is satisfied, either:
-Examples of structural interfaces with their structural types: +Examples of interfaces with core types:
@@ -2079,7 +2082,7 @@ interface{ ~[]*data; String() string } // []*data
-Examples of non-structural interfaces: +Examples of interfaces whithout core types:
@@ -4497,19 +4500,21 @@ min(1.0, 2) // illegal: default type float64 (for 1.0) doesn't match defaultConstraint type inference
-Constraint type inference infers type arguments from already known -type arguments by considering structural type constraints: -if the structural type
Tof a structural constraint is parameterized, -unifying a known type argument withTmay -infer type arguments for other type parameters used by the structural type. +Constraint type inference infers type arguments by considering type constraints. +If a type parameterPhas a constraint with a +core typeC, +unifyingPwithC+may infer additional type arguments, either the type argument forP, +or if that is already known, possibly the type arguments for type parameters +used inC.@@ -4523,8 +4528,8 @@ For instance, consider the type parameter list with type parameters
ListConstraint type inference can deduce the type of
@@ -4533,7 +4538,7 @@ type Bytes []byteElemfrom the type argument -forListbecauseElemis a type parameter in the structural constraint -~[]ElemforList. +forListbecauseElemis a type parameter in the core type +[]ElemofList. If the type argument isBytes:
-unifying the underlying type of Bytes with the structural constraint means
+unifying the underlying type of Bytes with the core type means
unifying []byte with []Elem. That unification succeeds and yields
the substitution map entry
Elem → byte.
@@ -4548,8 +4553,8 @@ substitution map M
A &RightAr
In the first phase, the type parameters B and C are unified
-with the structural type of their respective constraints. This adds the entries
+with the core type of their respective constraints. This adds the entries
B → []C and C → *A
to M.
@@ -5192,7 +5197,7 @@ as for non-constant x.
Converting a constant to a type that is not a type parameter yields a typed constant. -Converting a constant to a type parameter yields a non-constant value of that type. +Converting a constant to a type parameter yields a non-constant value of that type.
From 20c300bc70e10071bb15091f37a8bb3464cf13e3 Mon Sep 17 00:00:00 2001 From: Robert Griesemer+Date: Tue, 8 Feb 2022 18:40:28 -0800 Subject: [PATCH 021/179] spec: the type of a constant cannot be a type parameter Add corresponding rules and a couple of examples. Fixes #50202. Change-Id: I4287b5e2d0fd29a0c871795e07f1bb529c9c6004 Reviewed-on: https://go-review.googlesource.com/c/go/+/384240 Trust: Robert Griesemer Reviewed-by: Ian Lance Taylor --- doc/go_spec.html | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index a1800dcb5d..4d8312a917 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1,6 +1,6 @@ @@ -679,6 +679,8 @@ or conversion, or implicitly when used in a operand in an expression. It is an error if the constant value cannot be represented as a value of the respective type. +If the type is a type parameter, the constant is converted into a non-constant +value of the type parameter. @@ -2312,7 +2314,8 @@ ExpressionList = Expression { "," Expression } .
If the type is present, all constants take the type specified, and -the expressions must be assignable to that type. +the expressions must be assignable to that type, +which must not be a type parameter. If the type is omitted, the constants take the individual types of the corresponding expressions. If the expression values are untyped constants, @@ -5197,7 +5200,6 @@ as for non-constant
x.Converting a constant to a type that is not a type parameter yields a typed constant. -Converting a constant to a type parameter yields a non-constant value of that type.
@@ -5215,6 +5217,29 @@ int(1.2) // illegal: 1.2 cannot be represented as an int string(65.0) // illegal: 65.0 is not an integer constant++Converting a constant to a type parameter yields a non-constant value of that type, +with the value represented as a value of the type argument that the type parameter +is instantiated with. +For example, given the function: +
+ ++func f[P ~float32|~float64]() { + … P(1.1) … +} ++ ++the conversion
+P(1.1)results in a non-constant value of typeP+and the value1.1is represented as afloat32or afloat64+depending on the type argument forf. +Accordingly, iffis instantiated with afloat32type, +the numeric value of the expressionP(1.1) + 1.2will be computed +with the same precision as the corresponding non-constantfloat32+addition. +A non-constant value
xcan be converted to typeTin any of these cases: From 9867262dfd9b1ba2f212c24dbf26758f81d7cd58 Mon Sep 17 00:00:00 2001 From: Robert GriesemerDate: Wed, 9 Feb 2022 12:43:21 -0800 Subject: [PATCH 022/179] spec: document behavior of generic type switch cases Fixes #51110. Change-Id: I11370417f1ef435b05dfab18eeabc2c3c1b7b8a1 Reviewed-on: https://go-review.googlesource.com/c/go/+/384674 Trust: Robert Griesemer Trust: Dan Scales Reviewed-by: Dan Scales Reviewed-by: Ian Lance Taylor --- doc/go_spec.html | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/doc/go_spec.html b/doc/go_spec.html index 4d8312a917..c0ed27730f 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -6253,6 +6253,32 @@ if v == nil { }
+A type parameter or a parameterized type +may be used as a type in a case. If upon instantiation that type turns +out to duplicate another entry in the switch, the first matching case is chosen. +
+ +
+func f[P any](x any) int {
+ switch x.(type) {
+ case P:
+ return 0
+ case string:
+ return 1
+ case []P:
+ return 2
+ case []byte:
+ return 3
+ default:
+ return 4
+ }
+}
+
+var v1 = f[string]("foo") // v1 == 0
+var v2 = f[byte]([]byte{}) // v2 == 2
+
+
The type switch guard may be preceded by a simple statement, which
executes before the guard is evaluated.
From 2e2ef31778800856d9db87ad06cc963ef2530eeb Mon Sep 17 00:00:00 2001
From: Robert Griesemer
- TODO: https://golang.org/cl/321889: allocate hiter as part of MapIter -
- -- TODO: https://golang.org/cl/345486: optimize for maps with string keys -
- ++,
-, *, /) apply to
integer, floating-point, and
-complex types; + also applies to stringscomplex types; + also applies to strings.
The bitwise logical and shift operators apply to integers only.
@@ -4772,6 +4772,37 @@ The bitwise logical and shift operators apply to integers only.
>> right shift integer >> integer >= 0
++Excluding shifts, if the operand type is a type parameter, +it must have specific types, and the operator must +apply to each specific type. +The operands are represented as values of the type argument that the type parameter +is instantiated with, and the operation is computed +with the precision of that type argument. For example, given the function: +
+ +
+func dotProduct[F ~float32|~float64](v1, v2 []F) F {
+ var s F
+ for i, x := range v1 {
+ y := v2[i]
+ s += x * y
+ }
+ return s
+}
+
+
+
+the the product x * y and the addition s += x * y
+are computed with float32 or float64 precision,
+respectively, depending on the type argument for F.
+
+For shifts, the core type of both operands must be +an integer. +
+@@ -4857,10 +4888,10 @@ follows:
-For unsigned integer values, the operations +,
+For unsigned integer values, the operations +,
-, *, and << are
computed modulo 2n, where n is the bit width of
-the unsigned integer's type.
+the unsigned integer's type.
Loosely speaking, these unsigned integer operations
discard high bits upon overflow, and programs may rely on "wrap around".
x < x + 1 is always true.
-
@@ -4931,7 +4961,6 @@ s += " and good bye" String addition creates a new string by concatenating the operands.
-@@ -5220,7 +5249,7 @@ string(65.0) // illegal: 65.0 is not an integer constant
Converting a constant to a type parameter yields a non-constant value of that type, with the value represented as a value of the type argument that the type parameter -is instantiated with. +is instantiated with. For example, given the function:
From 99b61be9f573ca46f4a4160e536abcb62180638a Mon Sep 17 00:00:00 2001 From: Robert Griesemer
-Each type T has an underlying type: If T
-is one of the predeclared boolean, numeric, or string types, or a type literal,
-the corresponding underlying type is T itself.
-Otherwise, T's underlying type is the underlying type of the
-type to which T refers in its type
-declaration. Accordingly, the underlying type of a type parameter is the
-underlying type of its type constraint, which
-is always an interface.
-
-type (
- A1 = string
- A2 = A1
-)
-
-type (
- B1 string
- B2 B1
- B3 []B1
- B4 B3
-)
-
-func f[P any](x P) { … }
-
-
-
-The underlying type of string, A1, A2, B1,
-and B2 is string.
-The underlying type of []B1, B3, and B4 is []B1.
-The underlying type of P is interface{}.
-
-The method set of a type determines the methods that can be -called on an operand of that type. -Every type has a (possibly empty) method set associated with it: -
- -T consists of all
-methods declared with receiver type T.
-T
-(where T is neither a pointer nor an interface)
-is the set of all methods declared with receiver *T or T.
--Further rules apply to structs (and pointer to structs) containing embedded fields, -as described in the section on struct types. -Any other type has an empty method set. -
- --In a method set, each method must have a -unique -non-blank method name. -
-@@ -1748,6 +1675,171 @@ The properties of a type parameter are determined by its
+Each type T has an underlying type: If T
+is one of the predeclared boolean, numeric, or string types, or a type literal,
+the corresponding underlying type is T itself.
+Otherwise, T's underlying type is the underlying type of the
+type to which T refers in its type
+declaration. The underlying type of a type parameter is the
+underlying type of its type constraint, which
+is always an interface.
+
+type (
+ A1 = string
+ A2 = A1
+)
+
+type (
+ B1 string
+ B2 B1
+ B3 []B1
+ B4 B3
+)
+
+func f[P any](x P) { … }
+
+
+
+The underlying type of string, A1, A2, B1,
+and B2 is string.
+The underlying type of []B1, B3, and B4 is []B1.
+The underlying type of P is interface{}.
+
+Each non-interface type T has a core type, which is the
+underlying type of T.
+
+An interface T has a core type if one of the following
+conditions is satisfied:
+
U which is the underlying type
+of all types in the type set of T; or
+T contains only channel types
+with identical element type E, and all directional channels have the same
+direction.
++All other interfaces don't have a core type. +
+ ++The core type of an interface is, depending on the condition that is satisfied, either: +
+ +U; or
+chan E if T contains only bidirectional
+channels, or the type chan<- E or <-chan E
+depending on the direction of the directional channels present.
++Examples of interfaces with core types: +
+ +
+type Celsius float32
+type Kelvin float32
+
+interface{ int } // int
+interface{ Celsius|Kelvin } // float32
+interface{ ~chan int } // chan int
+interface{ ~chan int|~chan<- int } // chan<- int
+interface{ ~[]*data; String() string } // []*data
+
+
++Examples of interfaces whithout core types: +
+ +
+interface{} // no single underlying type
+interface{ Celsius|float64 } // no single underlying type
+interface{ chan int | chan<- string } // channels have different element types
+interface{ <-chan int | chan<- int } // directional channels have different directions
+
+
+
+An interface specification that contains type elements
+defines a (possibly empty) set of specific types.
+Loosely speaking, these are the types T that appear in the
+interface definition in terms of the form T, ~T,
+or in unions of such terms.
+
+More precisely, for a given interface, the set of specific types corresponds to +the set 𝑅 of representative types of the interface, if 𝑅 is non-empty and finite. +Otherwise, if 𝑅 is empty or infinite, the interface has no specific types. +
+ ++For a given interface, type element or type term, the set 𝑅 of representative types is defined as follows: +
+ +T or a term of the form ~T,
+ 𝑅 is the set consisting of the type T.
+ t1|t2|…|tn,
+ 𝑅 is the union of the representative types of the terms.
+ +An interface may have specific types even if its type set +is empty. +
+ ++Examples of interfaces with their specific types: +
+ +
+interface{} // no specific types
+interface{ int } // int
+interface{ ~string } // string
+interface{ int|~string } // int, string
+interface{ Celsius|Kelvin } // Celsius, Kelvin
+interface{ float64|any } // no specific types (union is all types)
+interface{ int; m() } // int (but type set is empty because int has no method m)
+interface{ ~int; m() } // int (but type set is infinite because many integer types have a method m)
+interface{ int; any } // int
+interface{ int; string } // no specific types (intersection is empty)
+
+
@@ -1888,7 +1980,7 @@ by a value of type T.
Additionally, if x's type V or T are type parameters
-with specific types, x
+with specific types, x
is assignable to a variable of type T if one of the following conditions applies:
T's component type (float32
-If T is a type parameter with specific types,
+If T is a type parameter with specific types,
x is representable by a value of type T if x is representable
by a value of each specific type of T.
@@ -1972,128 +2064,43 @@ x T x is not representable by a value of T because
1e1000 float64 1e1000 overflows to IEEE +Inf after rounding
-Structure of interfaces
+Method sets
-An interface specification which contains type elements
-defines a (possibly empty) set of specific types.
-Loosely speaking, these are the types T that appear in the
-interface definition in terms of the form T, ~T,
-or in unions of such terms.
-
-
-
-More precisely, for a given interface, the set of specific types corresponds to
-the set 𝑅 of representative types of the interface, if 𝑅 is non-empty and finite.
-Otherwise, if 𝑅 is empty or infinite, the interface has no specific types.
-
-
-
-For a given interface, type element or type term, the set 𝑅 of representative types is defined as follows:
+The method set of a type determines the methods that can be
+called on an operand of that type.
+Every type has a (possibly empty) method set associated with it:
- - For an interface with no type elements, 𝑅 is the (infinite) set of all types.
-
+- The method set of a defined type
T consists of all
+methods declared with receiver type T.
+
- - For an interface with type elements,
- 𝑅 is the intersection of the representative types of its type elements.
-
+-
+The method set of a pointer to a defined type
T
+(where T is neither a pointer nor an interface)
+is the set of all methods declared with receiver *T or T.
+
- - For a non-interface type term
T or a term of the form ~T,
- 𝑅 is the set consisting of the type T.
-
-
- - For a union of terms
-
t1|t2|…|tn,
- 𝑅 is the union of the representative types of the terms.
-
+- The method set of an interface type is the intersection
+of the method sets of each type in the interface's type set
+(the resulting method set is usually just the set of declared methods in the interface).
+
-An interface may have specific types even if its type set
-is empty.
+Further rules apply to structs (and pointer to structs) containing embedded fields,
+as described in the section on struct types.
+Any other type has an empty method set.
-Examples of interfaces with their specific types:
+In a method set, each method must have a
+unique
+non-blank method name.
-
-type Celsius float32
-type Kelvin float32
-
-interface{} // no specific types
-interface{ int } // int
-interface{ ~string } // string
-interface{ int|~string } // int, string
-interface{ Celsius|Kelvin } // Celsius, Kelvin
-interface{ float64|any } // no specific types (union is all types)
-interface{ int; m() } // int (but type set is empty because int has no method m)
-interface{ ~int; m() } // int (but type set is infinite because many integer types have a method m)
-interface{ int; any } // int
-interface{ int; string } // no specific types (intersection is empty)
-
-
-
-An interface T has a core type if one of the following
-conditions is satisfied:
-
-
-
--
-There is a single type
U which is the underlying type
-of all types in the type set of T; or
-
--
-the type set of
T contains only channel types
-with identical element type E, and all directional channels have the same
-direction.
-
-
-
-
-All other interfaces don't have a core type.
-
-
-
-The core type is, depending on the condition that is satisfied, either:
-
-
-
--
-the type
U; or
-
--
-the type
chan E if T contains only bidirectional
-channels, or the type chan<- E or <-chan E
-depending on the direction of the directional channels present.
-
-
-
-
-Examples of interfaces with core types:
-
-
-
-interface{ int } // int
-interface{ Celsius|Kelvin } // float32
-interface{ ~chan int } // chan int
-interface{ ~chan int|~chan<- int } // chan<- int
-interface{ ~[]*data; String() string } // []*data
-
-
-
-Examples of interfaces whithout core types:
-
-
-
-interface{} // no single underlying type
-interface{ Celsius|float64 } // no single underlying type
-interface{ chan int | chan<- string } // channels have different element types
-interface{ <-chan int | chan<- int } // directional channels have different directions
-
-
Blocks
@@ -3783,7 +3790,7 @@ For a of map type M:
For a of type parameter type P:
- P must have specific types.
+ P must have specific types.
- The index expression
a[x] must be valid for values
of all specific types of P.
- The element types of all specific types of
P must be identical.
@@ -4513,7 +4520,7 @@ min(1.0, 2) // illegal: default type float64 (for 1.0) doesn't match default
Constraint type inference infers type arguments by considering type constraints.
If a type parameter P has a constraint with a
-core type C,
+core type C,
unifying P with C
may infer additional type arguments, either the type argument for P,
or if that is already known, possibly the type arguments for type parameters
@@ -4774,7 +4781,7 @@ The bitwise logical and shift operators apply to integers only.
Excluding shifts, if the operand type is a type parameter,
-it must have specific types, and the operator must
+it must have specific types, and the operator must
apply to each specific type.
The operands are represented as values of the type argument that the type parameter
is instantiated with, and the operation is computed
@@ -5314,7 +5321,7 @@ in any of these cases:
Additionally, if T or
x's type V are type
-parameters with specific types, x
+parameters with specific types, x
can also be converted to type T if one of the following conditions applies:
@@ -7023,7 +7030,7 @@ cap(s) [n]T, *[n]T array length (== n)
If the argument type is a type parameter P,
-P must have specific types, and
+P must have specific types, and
the call len(e) (or cap(e) respectively) must be valid for
each specific type of P.
The result is the length (or capacity, respectively) of the argument whose type
From c4b87b8d08af1243a8ef0add245f10f878879a57 Mon Sep 17 00:00:00 2001
From: Suvaditya Sur
+By definition, a core type is never a defined type, +type parameter, or +interface type. +
+Examples of interfaces with core types:
@@ -2994,6 +3000,13 @@ non-blank identifier denoting a or a parenthesized expression. +
+Operand = Literal | OperandName [ TypeArgs ] | "(" Expression ")" .
+Literal = BasicLit | CompositeLit | FunctionLit .
+BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
+OperandName = identifier | QualifiedIdent .
+
+
An operand name denoting a type-parameterized function may be followed by a list of type arguments; the @@ -3005,13 +3018,6 @@ The blank identifier may appear as an operand only on the left-hand side of an assignment.
-
-Operand = Literal | OperandName [ TypeArgs ] | "(" Expression ")" .
-Literal = BasicLit | CompositeLit | FunctionLit .
-BasicLit = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
-OperandName = identifier | QualifiedIdent .
-
-
@@ -3038,8 +3044,7 @@ math.Sin // denotes the Sin function in package math
-Composite literals construct values for structs, arrays, slices, and maps -and create a new value each time they are evaluated. +Composite literals construct new composite values each time they are evaluated. They consist of the type of the literal followed by a brace-bound list of elements. Each element may optionally be preceded by a corresponding key.
@@ -3057,11 +3062,12 @@ Element = Expression | LiteralValue .
-The LiteralType's underlying type must be a struct, array, slice, or map type
+The LiteralType's core type T
+must be a struct, array, slice, or map type
(the grammar enforces this constraint except when the type is given
as a TypeName).
The types of the elements and keys must be assignable
-to the respective field, element, and key types of the literal type;
+to the respective field, element, and key types of type T;
there is no additional conversion.
The key is interpreted as a field name for struct literals,
an index for array and slice literals, and a key for map literals.
@@ -3318,6 +3324,8 @@ f.p[i].x()
For a primary expression x
that is not a package name, the
@@ -3361,8 +3369,7 @@ The following rules apply to selectors:
For a value x of type T or *T
where T is not a pointer or interface type,
x.f denotes the field or method at the shallowest depth
-in T where there
-is such an f.
+in T where there is such an f.
If there is not exactly one f
with shallowest depth, the selector expression is illegal.
a is not a map:
x must be of integer type or an untyped constantx must be an untyped constant or its
+ core type must be an integerintint
-For a string, array, pointer to array, or slice a, the primary expression
+The primary expression
@@ -3852,7 +3860,9 @@ a[low : high]
-constructs a substring or slice. The indices low and
+constructs a substring or slice. The core type of
+a must be a string, array, pointer to array, or slice.
+The indices low and
high select which elements of operand a appear
in the result. The result has indices starting at 0 and length equal to
high - low.
@@ -3928,7 +3938,7 @@ s2[1] = 42 // s2[1] == s1[2] == a[5] == 42; they all refer to the same under
-For an array, pointer to array, or slice a (but not a string), the primary expression
+The primary expression
@@ -3939,6 +3949,8 @@ a[low : high : max] constructs a slice of the same type, and with the same length and elements as the simple slice expressiona[low : high]. Additionally, it controls the resulting slice's capacity by setting it tomax - low. Only the first index may be omitted; it defaults to 0. +The core type ofamust be an array, pointer to array, +or slice (but not a string). After slicing the arraya@@ -4044,8 +4056,8 @@ No run-time panic occurs in this case.Calls
-Given an expression
fof function type -F, +Given an expressionfwith a core type +Fof function type,@@ -5148,7 +5160,8 @@ var x *int = nil+Receive operator
-For an operand
chof channel type, +For an operandchwhose core type is a +channel, the value of the receive operation<-chis the value received from the channelch. The channel direction must permit receive operations, and the type of the receive operation is the element type of the channel. @@ -5861,7 +5874,8 @@ len("foo") // illegal if len is the built-in functionA send statement sends a value on a channel. -The channel expression must be of channel type, +The channel expression's core type +must be a channel, the channel direction must permit send operations, and the type of the value to be sent must be assignable to the channel's element type. @@ -6407,7 +6421,8 @@ RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
The expression on the right in the "range" clause is called the range expression, -which may be an array, pointer to an array, slice, string, map, or channel permitting +its core type must be +an array, pointer to an array, slice, string, map, or channel permitting receive operations. As with an assignment, if present the operands on the left must be addressable or map index expressions; they @@ -6992,9 +7007,10 @@ they cannot be used as function values.
Close
-For a channel
c, the built-in functionclose(c)+For an argumentchwith a core type +that is a channel, the built-in functioncloserecords that no more values will be sent on the channel. -It is an error ifcis a receive-only channel. +It is an error ifchis a receive-only channel. Sending to or closing a closed channel causes a run-time panic. Closing the nil channel also causes a run-time panic. After callingclose, and after any previously @@ -7110,24 +7126,25 @@ of the location.The built-in function
maketakes a typeT, -which must be a slice, map or channel type, optionally followed by a type-specific list of expressions. +The core type ofTmust +be a slice, map or channel. It returns a value of typeT(not*T). The memory is initialized as described in the section on initial values.-Call Type T Result +Call Core type Result -make(T, n) slice slice of type T with length n and capacity n -make(T, n, m) slice slice of type T with length n and capacity m +make(T, n) slice slice of type T with length n and capacity n +make(T, n, m) slice slice of type T with length n and capacity m -make(T) map map of type T -make(T, n) map map of type T with initial space for approximately n elements +make(T) map map of type T +make(T, n) map map of type T with initial space for approximately n elements -make(T) channel unbuffered channel of type T -make(T, n) channel buffered channel of type T, buffer size n +make(T) channel unbuffered channel of type T +make(T, n) channel buffered channel of type T, buffer size n@@ -7169,21 +7186,20 @@ by the arguments overlaps.The variadic function
append-appends zero or more valuesx-tosof typeS, which must be a slice type, and -returns the resulting slice, also of typeS. -The valuesxare passed to a parameter of type...T-whereTis the element type of -Sand the respective -parameter passing rules apply. -As a special case,appendalso accepts a first argument -assignable to type[]bytewith a second argument of -string type followed by.... This form appends the -bytes of the string. +appends zero or more valuesxto a slices+and returns the resulting slice. +The core type ofsmust be a slice +of the form[]E. +The valuesxare passed to a parameter of type...E+and the respective parameter +passing rules apply. +As a special case, if the core type ofsis[]byte, +appendalso accepts a second argument with core typestring+followed by.... This form appends the bytes of the string.-append(s S, x ...T) S // T is the element type of S +append(s S, x ...E) S // E is the element type of the core type of S@@ -7211,12 +7227,12 @@ b = append(b, "bar"...) // append string contents b == []byte{'b The function
@@ -7252,6 +7268,12 @@ to the key type ofcopycopies slice elements from a sourcesrcto a destinationdstand returns the number of elements copied. -Both arguments must have identical element typeTand must be -assignable to a slice of type[]T. +The core types of both arguments must be slices +with identical element type. The number of elements copied is the minimum oflen(src)andlen(dst). -As a special case,copyalso accepts a destination argument assignable -to type[]bytewith a source argument of a string type. +As a special case, if the destination's core type is[]byte, +copyalso accepts a source argument with core typestring. This form copies the bytes from the string into the byte slice.m. delete(m, k) // remove element m[k] from map m+If the type of
+mis a type parameter, +it must have specific types, all specific types +must be maps, and they must all have identical key types. +If the map
misnilor the elementm[k]does not exist,deleteis a no-op. @@ -7260,6 +7282,8 @@ does not exist,deleteis a no-op.Manipulating complex numbers
+ +Three functions assemble and disassemble complex numbers. The built-in function
complexconstructs a complex From ca3fae1e0e2a4d7d1a6ba9eeb137d1d0f001e0a6 Mon Sep 17 00:00:00 2001 From: Robert GriesemerDate: Wed, 9 Feb 2022 21:49:10 -0800 Subject: [PATCH 036/179] spec: use the term "generic" rather than "(type-)parameterized" This makes the prose easier to read while being just as precise. Change-Id: Ie46c6c5042f419de9fdeb1c75bb72b5a40c37073 Reviewed-on: https://go-review.googlesource.com/c/go/+/384774 Trust: Robert Griesemer Run-TryBot: Robert Griesemer Reviewed-by: Ian Lance Taylor TryBot-Result: Gopher Robot --- doc/go_spec.html | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index c7f93c953d..25a2fd96a1 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -790,7 +790,7 @@ If a variable has not yet been assigned a value, its value is the A type determines a set of values together with operations and methods specific to those values. A type may be denoted by a type name, if it has one, which must be -followed by type arguments if the type is parameterized. +followed by type arguments if the type is generic. A type may also be specified using a type literal, which composes a type from existing types.
@@ -1662,10 +1662,10 @@ A type parameter is an (unqualified) type name declared in the function declaration or type definition; or in the receiver specification of a method declaration that is associated -with a parameterized type. +with a generic type. A type parameter acts as a place holder for an (as of yet) unknown type in the declaration; the type parameter is replaced with a type argument upon -instantiation of the parameterized function or type. +instantiation of the generic function or type.@@ -2197,13 +2197,13 @@ Go is lexically scoped using blocks:
If the type definition specifies type parameters, -the type name denotes a parameterized type. -Parameterized types must be instantiated when they +the type name denotes a generic type. +Generic types must be instantiated when they are used.
@@ -2581,9 +2581,9 @@ func f[T any]() {-A parameterized type may also have methods associated with it. In this case, +A generic type may also have methods associated with it. In this case, the method receivers must declare the same number of type parameters as -present in the parameterized type definition. +present in the generic type definition.
@@ -2595,7 +2595,7 @@ func (l *List[T]) Len() int { … }
A type parameter list declares the type parameters
-in a type-parameterized function or type declaration.
+in a generic function or type declaration.
The type parameter list looks like an ordinary function parameter list
except that the type parameter names must all be present and the list is enclosed
in square brackets rather than parentheses.
@@ -2628,7 +2628,7 @@ has a corresponding (meta-)type which is called its
-A parsing ambiguity arises when the type parameter list for a parameterized type
+A parsing ambiguity arises when the type parameter list for a generic type
declares a single type parameter with a type constraint of the form *C
or (C) where C is not a (possibly parenthesized)
type literal:
@@ -2868,8 +2868,8 @@ func IndexRune(s string, r rune) int {
If the function declaration specifies type parameters,
-the function name denotes a type-parameterized function.
-Type-parameterized functions must be instantiated when they
+the function name denotes a generic function.
+Generic functions must be instantiated when they
are used.
@@ -2954,7 +2954,7 @@ to the base type Point.
-If the receiver base type is a parameterized type, the
+If the receiver base type is a generic type, the
receiver specification must declare corresponding type parameters for the method
to use. This makes the receiver type parameters available to the method.
@@ -3008,7 +3008,7 @@ OperandName = identifier | QualifiedIdent .
-An operand name denoting a type-parameterized function +An operand name denoting a generic function may be followed by a list of type arguments; the resulting operand is an instantiated function.
@@ -4083,7 +4083,7 @@ pt.Scale(3.5) // method call with receiver pt
-If f denotes a parameterized function, it must be
+If f denotes a generic function, it must be
instantiated before it can be called
or used as a function value.
-A parameterized function or type is instantiated by substituting type arguments +A generic function or type is instantiated by substituting type arguments for the type parameters. Instantiation proceeds in two phases:
-Instantiating a type results in a new non-parameterized named type; -instantiating a function produces a new non-parameterized function. +Instantiating a type results in a new non-generic named type; +instantiating a function produces a new non-generic function.
@@ -4257,10 +4257,10 @@ the remaining arguments to be inferred. Loosely speaking, type arguments may be-Parameterized types, and parameterized functions that are not called, +Generic types, and generic functions that are not called, require a type argument list for instantiation; if the list is partial, all remaining type arguments must be inferrable. -Calls to parameterized functions may provide a (possibly partial) type +Calls to generic functions may provide a (possibly partial) type argument list, or may omit it entirely if the omitted type arguments are inferrable from the ordinary (non-type) function arguments.
@@ -4429,7 +4429,7 @@ parameters used byT.-For instance, given the type-parameterized function +For instance, given the generic function
@@ -6304,7 +6304,7 @@ if v == nil {-A type parameter or a parameterized type +A type parameter or a generic type may be used as a type in a case. If upon instantiation that type turns out to duplicate another entry in the switch, the first matching case is chosen.
From 30501bbef9fcfc9d53e611aaec4d20bb3cdb8ada Mon Sep 17 00:00:00 2001 From: Robert GriesemerDate: Thu, 10 Feb 2022 16:02:48 -0800 Subject: [PATCH 037/179] spec: introduce notion of basic interface, misc. fine-tuning A basic interface is a classical Go interface containing only methods or embedding basic interfaces. Use this to simplify rule about what interfaces may be used where. The term "basic interface" will also be useful when talking about various interfaces in general. Fix rule restricting union terms: as it was written it also excluded interface terms with non-empty method sets due to embedded non-interface types with methods. Split the large section on interfaces into three smaller pieces by introducing section titles. Change-Id: I142a4d5609eb48aaa0f7800b5b85c1d6c0703fcb Reviewed-on: https://go-review.googlesource.com/c/go/+/384994 Trust: Robert Griesemer Run-TryBot: Robert Griesemer TryBot-Result: Gopher Robot Reviewed-by: Ian Lance Taylor --- doc/go_spec.html | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index 25a2fd96a1..3405b7d887 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1226,11 +1226,15 @@ where a type element is a union of one or more type terms. A type term is either a single type or a single underlying type. + Basic interfaces
+In its most basic form an interface specifies a (possibly empty) list of methods. The type set defined by such an interface is the set of types which implement all of those methods, and the corresponding method set consists exactly of the methods specified by the interface. +Interfaces whose type sets can be defined entirely by a list of methods are called +basic interfaces.
@@ -1315,6 +1319,8 @@ they implement the+Lockerinterface as well as theFileinterface. +Embedded interfaces
+In a slightly more general form an interface
Tmay use a (possibly qualified) interface type @@ -1359,8 +1365,10 @@ type ReadCloser interface { }General interfaces
+-Finally, in their most general form, an interface element may also be an arbitrary type term +In their most general form, an interface element may also be an arbitrary type term
T, or a term of the form~Tspecifying the underlying typeT, or a union of termst1|t2|…|tn. Together with method specifications, these elements enable the precise @@ -1462,21 +1470,21 @@ interface {Implementation restriction: -A union with more than one term cannot contain interface types -with non-empty method sets or which -are or embed the predeclared identifier -
comparable. +A union with more than one term cannot contain the +predeclared identifiercomparable+or interfaces that specify methods, or embedcomparableor interfaces +that specify methods.-Interfaces that contain non-interface types, terms of the form
~T, -or unions may only be used as type constraints, or as elements of other interfaces used -as constraints. They cannot be the types of values or variables, or components of other, +Interfaces that are not basic may only be used as type +constraints, or as elements of other interfaces used as constraints. +They cannot be the types of values or variables, or components of other, non-interface types.-var x Floats // illegal: Floats is restricted by float32 and float64 +var x Floats // illegal: Floats is not a basic interface var x interface{} = Floats(nil) // illegal @@ -1714,7 +1722,7 @@ The underlying type ofPisinterface{}.Core types
-Each non-interface type
@@ -2665,9 +2673,9 @@ TypeConstraint = TypeElem .Thas a core type, which is the +Each non-interface typeThas a core type, which is the same as the underlying type ofT.-If the constraint is an interface literal containing exactly one embedded type element -
interface{E}, in a type parameter list the enclosinginterface{ … }-may be omitted for convenience: +If the constraint is an interface literal of the forminterface{E}where +Eis an embedded type element (not a method), in a type parameter list +the enclosinginterface{ … }may be omitted for convenience:From 9fdcfb7c10b464ffab815892f5fc77d68ed35714 Mon Sep 17 00:00:00 2001 From: Kevin Burke-Date: Thu, 10 Feb 2022 20:44:03 -0800 Subject: [PATCH 038/179] doc: fix spelling error in link ID Change-Id: I6de236442f213ab4b4f19ec881add4923d8bfd8d Reviewed-on: https://go-review.googlesource.com/c/go/+/385054 Reviewed-by: Ian Lance Taylor Trust: Kevin Burke --- doc/go_spec.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index 3405b7d887..49533b067d 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -1365,7 +1365,7 @@ type ReadCloser interface { } General interfaces
+General interfaces
In their most general form, an interface element may also be an arbitrary type term From e50f0f372b07149e9cf16b8fec80d2d72efe2a87 Mon Sep 17 00:00:00 2001 From: Robert Griesemer
Date: Thu, 10 Feb 2022 20:10:33 -0800 Subject: [PATCH 039/179] spec: describe processing of function arguments for type inference more precisely The outcome of type inference depends critically on when function argument type inference stops processing arguments. Describe this and explain an example with some detail. Also: In the section on the built-in function delete, refer to the value rather than the type of the second argument, as it may be an untyped constant. Change-Id: Ice7fbb33f985afe082380b8d37eaf763238a3818 Reviewed-on: https://go-review.googlesource.com/c/go/+/385034 Trust: Robert Griesemer Reviewed-by: Ian Lance Taylor --- doc/go_spec.html | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/go_spec.html b/doc/go_spec.html index 49533b067d..061f933ae8 100644 --- a/doc/go_spec.html +++ b/doc/go_spec.html @@ -4514,6 +4514,12 @@ Each list is processed in a separate phase:
+While unification is successful, processing of each list continues until all list elements +are considered, even if all type arguments are inferred before the last list element has +been processed. +
+Example:
@@ -4527,6 +4533,13 @@ min(1.0, 2.0) // T is float64, inferred from default type for 1.0 and matches d min(1.0, 2) // illegal: default type float64 (for 1.0) doesn't match default type int (for 2) +
+In the example min(1.0, 2), processing the function argument 1.0
+yields the substitution map entry T → float64. Because
+processing continues until all untyped arguments are considered, an error is reported. This
+ensures that type inference does not depend on the order of the untyped arguments.
+
An interface type defines a type set.
A variable of interface type can store a value of any type that is in the type
-set of the interface. Such a type is said to implement the interface.
+set of the interface. Such a type is said to
+implement the interface.
The value of an uninitialized variable of interface type is nil.
+By construction, an interface's type set never contains an interface type. +
+
// An interface representing only the type int.
interface {
@@ -1519,6 +1524,27 @@ type Bad2 interface {
}
+
+A type T implements an interface I if
+
T is not an interface and is an element of the type set of I; or
+T is an interface and the type set of T is a subset of the
+ type set of I.
+
+A value x of type T implements an interface if T
+implements the interface.
+
@@ -1978,7 +2004,7 @@ and at least one of V or T is not a n
T is an interface type, but not a type parameter, and
-x implements T.
+x implements T.
x is the predeclared identifier nil and T
@@ -2687,7 +2713,7 @@ type Constraint ~int // illegal: ~int is not inside a type paramet
@@ -4018,7 +4044,7 @@ In this case, T must implement the (inte
otherwise the type assertion is invalid since it is not possible for x
to store a value of type T.
If T is an interface type, x.(T) asserts that the dynamic type
-of x implements the interface T.
+of x implements the interface T.
If the type assertion holds, the value of the expression is the value @@ -4290,7 +4316,8 @@ Missing type arguments may be inferred by a series of steps, described be Each step attempts to use known information to infer additional type arguments. Type inference stops as soon as all type arguments are known. After type inference is complete, it is still necessary to substitute all type arguments -for type parameters and verify that each type argument implements the relevant constraint; +for type parameters and verify that each type argument +implements the relevant constraint; it is possible for an inferred type argument to fail to implement a constraint, in which case instantiation fails.
@@ -4344,7 +4371,7 @@ The process stops as soon as M has a type argument for each type paramete If an inference step fails, or if M is still missing type arguments after the last step, type inference fails. -
Type inference is based on type unification. A single unification step
@@ -4421,7 +4448,7 @@ and the type literal []E, unification compares []float64
-Function argument type inference
+
Function argument type inference
@@ -1688,25 +1688,6 @@ and a second goroutine receives them, the values are
received in the order sent.
-A type parameter is an (unqualified) type name declared in the -type parameter list of a -function declaration or -type definition; or in the receiver specification -of a method declaration that is associated -with a generic type. -A type parameter acts as a place holder for an (as of yet) unknown type in the declaration; -the type parameter is replaced with a type argument upon -instantiation of the generic function or type. -
- --The properties of a type parameter are determined by its -type constraint. -
-By definition, a core type is never a defined type, -type parameter, or +type parameter, or interface type.
@@ -2047,7 +2028,7 @@ toT.
A constant x is representable
by a value of type T,
-where T is not a type parameter,
+where T is not a type parameter,
if one of the following conditions applies:
-A type parameter list declares the type parameters -in a generic function or type declaration. +A type parameter list declares the type parameters of a generic function or type declaration. The type parameter list looks like an ordinary function parameter list except that the type parameter names must all be present and the list is enclosed in square brackets rather than parentheses. @@ -2642,9 +2622,11 @@ TypeParamDecl = IdentifierList TypeConstraint .
-Each identifier declares a type parameter. All non-blank names in the list must be unique. -Each type parameter is a new and different named type. +Each name declares a type parameter, which is a new and different named type +that acts as a place holder for an (as of yet) unknown type in the declaration. +The type parameter is replaced with a type argument upon +instantiation of the generic function or type.
@@ -2686,6 +2668,12 @@ type T[P interface{*C}] …
type T[P *C,] …
++Type parameters may also be declared by the receiver specification +of a method declaration associated +with a generic type. +
+
@@ -3829,7 +3817,7 @@ For a of map type M:
-For a of type parameter type P:
+For a of type parameter type P:
P must have specific types.
For an expression x of interface type,
-but not a type parameter, and a type T,
+but not a type parameter, and a type T,
the primary expression
-Excluding shifts, if the operand type is a type parameter,
+Excluding shifts, if the operand type is a type parameter,
it must have specific types, and the operator must
apply to each specific type.
The operands are represented as values of the type argument that the type parameter
@@ -5295,7 +5283,7 @@ as for non-constant x.
-Converting a constant to a type that is not a type parameter +Converting a constant to a type that is not a type parameter yields a typed constant.
@@ -5350,7 +5338,7 @@ in any of these cases:x's type and T are not
- type parameters but have
+ type parameters but have
identical underlying types.
T against the dynamic type of the
expression x. As with type assertions, x must be of
interface type, but not a
-type parameter, and each non-interface type
+type parameter, and each non-interface type
T listed in a case must implement the type of x.
The types listed in the cases of a type switch must all be
different.
@@ -6351,7 +6339,7 @@ if v == nil {
-A type parameter or a generic type +A type parameter or a generic type may be used as a type in a case. If upon instantiation that type turns out to duplicate another entry in the switch, the first matching case is chosen.
@@ -7092,7 +7080,7 @@ cap(s) [n]T, *[n]T array length (== n)
-If the argument type is a type parameter P,
+If the argument type is a type parameter P,
P must have specific types, and
the call len(e) (or cap(e) respectively) must be valid for
each specific type of P.
@@ -7316,7 +7304,7 @@ delete(m, k) // remove element m[k] from map m
-If the type of m is a type parameter,
+If the type of m is a type parameter,
it must have specific types, all specific types
must be maps, and they must all have identical key types.
+[For reviewers: Sections where we know of missing prose are marked like this. The markers will be removed before the release.] +
+@@ -1498,15 +1503,9 @@ type Floatish struct { } - -
-An interface type T may not embed itself
-or any interface type that embeds T, recursively.
+An interface type T may not embed any type element
+that is, contains, or embeds T, recursively.
@@ -1522,6 +1521,11 @@ type Bad1 interface {
type Bad2 interface {
Bad1
}
+
+// illegal: Bad3 cannot embed a union containing Bad3
+type Bad3 interface {
+ ~int | ~string | Bad3
+}
+[The definition of specific types is not quite correct yet.] +
+An interface specification that contains type elements defines a (possibly empty) set of specific types. @@ -3346,7 +3354,9 @@ f.p[i].x()
+[This section is missing rules for x.f where x's type is a type parameter and f is a field.] +
For a primary expression x
@@ -4557,14 +4567,6 @@ ensures that type inference does not depend on the order of the untyped argument
Constraint type inference infers type arguments by considering type constraints.
If a type parameter P has a constraint with a
@@ -4604,6 +4606,17 @@ Thus, in this example, constraint type inference can infer the second type argum
first one.
+Using the core type of a constraint may lose some information: In the (unlikely) case that
+the constraint's type set contains a single defined type
+N, the corresponding core type is N's underlying type rather than
+N itself. In this case, constraint type inference may succeed but instantiation
+will fail because the inferred type is not in the type set of the constraint.
+Thus, constraint type inference uses the adjusted core type of
+a constraint: if the type set contains a single type, use that type; otherwise use the
+constraint's core type.
+
Generally, constraint type inference proceeds in two phases: Starting with a given substitution map M @@ -4611,7 +4624,7 @@ substitution map M
-Additionally, if T or x's type V are type
+Additionally, if T or x's type V are type
parameters with specific types, x
can also be converted to type T if one of the following conditions applies:
delete is a no-op.
+[We don't support generic arguments for these built-ins for Go 1.18.] +
Three functions assemble and disassemble complex numbers.
From 875a6d40107d560473d1590425a096dd4cee346f Mon Sep 17 00:00:00 2001
From: Robert Findley
- TODO: https://golang.org/cl/353969: enable register ABI for PPC64 -
-
The
The
If the main module's
The
The
The
The
The
- TODO: https://golang.org/cl/240611: 240611: cmd/fix: add buildtag fix
+Go 1.17 introduced Since the release of Go 1.18 marks the end of support for Go 1.16,
+all supported versions of Go now understand
+For more information, see https://go.dev/design/draft-gobuild.
+
go command now supports a "Workspace" mode. If a
go.work file is found in the working directory or a
- parent directory, or one is specified using the -workfile
- flag, it will put the go command into workspace mode.
+ parent directory, or one is specified using the GOWORK
+ environment variable, it will put the go command into workspace mode.
In workspace mode, the go.work file will be used to
determine the set of main modules used as the roots for module
resolution, instead of using the normally-found go.mod
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 13a3f00d6f..63e7900e02 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -177,14 +177,6 @@
// directory, but it is not accessed. When -modfile is specified, an
// alternate go.sum file is also used: its path is derived from the
// -modfile flag by trimming the ".mod" extension and appending ".sum".
-// -workfile file
-// in module aware mode, use the given go.work file as a workspace file.
-// By default or when -workfile is "auto", the go command searches for a
-// file named go.work in the current directory and then containing directories
-// until one is found. If a valid go.work file is found, the modules
-// specified will collectively be used as the main modules. If -workfile
-// is "off", or a go.work file is not found in "auto" mode, workspace
-// mode is disabled.
// -overlay file
// read a JSON config file that provides an overlay for build operations.
// The file is a JSON struct with a single field, named 'Replace', that
@@ -2075,6 +2067,14 @@
// GOVCS
// Lists version control commands that may be used with matching servers.
// See 'go help vcs'.
+// GOWORK
+// In module aware mode, use the given go.work file as a workspace file.
+// By default or when GOWORK is "auto", the go command searches for a
+// file named go.work in the current directory and then containing directories
+// until one is found. If a valid go.work file is found, the modules
+// specified will collectively be used as the main modules. If GOWORK
+// is "off", or a go.work file is not found in "auto" mode, workspace
+// mode is disabled.
//
// Environment variables for use with cgo:
//
diff --git a/src/cmd/go/internal/base/flag.go b/src/cmd/go/internal/base/flag.go
index 2c72c7e562..120420a126 100644
--- a/src/cmd/go/internal/base/flag.go
+++ b/src/cmd/go/internal/base/flag.go
@@ -62,13 +62,6 @@ func AddModFlag(flags *flag.FlagSet) {
flags.Var(explicitStringFlag{value: &cfg.BuildMod, explicit: &cfg.BuildModExplicit}, "mod", "")
}
-// AddWorkfileFlag adds the workfile flag to the flag set. It enables workspace
-// mode for commands that support it by resetting the cfg.WorkFile variable
-// to "" (equivalent to auto) rather than off.
-func AddWorkfileFlag(flags *flag.FlagSet) {
- flags.Var(explicitStringFlag{value: &cfg.WorkFile, explicit: &cfg.WorkFileExplicit}, "workfile", "")
-}
-
// AddModCommonFlags adds the module-related flags common to build commands
// and 'go mod' subcommands.
func AddModCommonFlags(flags *flag.FlagSet) {
diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go
index 7f68d7bb62..deab3dddd0 100644
--- a/src/cmd/go/internal/cfg/cfg.go
+++ b/src/cmd/go/internal/cfg/cfg.go
@@ -49,10 +49,8 @@ var (
BuildWork bool // -work flag
BuildX bool // -x flag
- ModCacheRW bool // -modcacherw flag
- ModFile string // -modfile flag
- WorkFile string // -workfile flag
- WorkFileExplicit bool // whether -workfile was set explicitly
+ ModCacheRW bool // -modcacherw flag
+ ModFile string // -modfile flag
CmdName string // "build", "install", "list", "mod tidy", etc.
diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go
index e56dd8223f..c1adf8cef4 100644
--- a/src/cmd/go/internal/envcmd/env.go
+++ b/src/cmd/go/internal/envcmd/env.go
@@ -154,6 +154,10 @@ func ExtraEnvVars() []cfg.EnvVar {
}
modload.InitWorkfile()
gowork := modload.WorkFilePath()
+ // As a special case, if a user set off explicitly, report that in GOWORK.
+ if cfg.Getenv("GOWORK") == "off" {
+ gowork = "off"
+ }
return []cfg.EnvVar{
{Name: "GOMOD", Value: gomod},
{Name: "GOWORK", Value: gowork},
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index d1eaad1c12..28ddaac8f1 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -545,6 +545,14 @@ General-purpose environment variables:
GOVCS
Lists version control commands that may be used with matching servers.
See 'go help vcs'.
+ GOWORK
+ In module aware mode, use the given go.work file as a workspace file.
+ By default or when GOWORK is "auto", the go command searches for a
+ file named go.work in the current directory and then containing directories
+ until one is found. If a valid go.work file is found, the modules
+ specified will collectively be used as the main modules. If GOWORK
+ is "off", or a go.work file is not found in "auto" mode, workspace
+ mode is disabled.
Environment variables for use with cgo:
diff --git a/src/cmd/go/internal/list/list.go b/src/cmd/go/internal/list/list.go
index d9a7078ccf..8be9211935 100644
--- a/src/cmd/go/internal/list/list.go
+++ b/src/cmd/go/internal/list/list.go
@@ -316,7 +316,6 @@ For more about modules, see https://golang.org/ref/mod.
func init() {
CmdList.Run = runList // break init cycle
work.AddBuildFlags(CmdList, work.DefaultBuildFlags)
- base.AddWorkfileFlag(&CmdList.Flag)
}
var (
diff --git a/src/cmd/go/internal/modcmd/download.go b/src/cmd/go/internal/modcmd/download.go
index 6b8a010fd9..5bc6cbc4bb 100644
--- a/src/cmd/go/internal/modcmd/download.go
+++ b/src/cmd/go/internal/modcmd/download.go
@@ -70,7 +70,6 @@ func init() {
// TODO(jayconrod): https://golang.org/issue/35849 Apply -x to other 'go mod' commands.
cmdDownload.Flag.BoolVar(&cfg.BuildX, "x", false, "")
base.AddModCommonFlags(&cmdDownload.Flag)
- base.AddWorkfileFlag(&cmdDownload.Flag)
}
type moduleJSON struct {
diff --git a/src/cmd/go/internal/modcmd/graph.go b/src/cmd/go/internal/modcmd/graph.go
index 9b6aa1fb14..9568c65740 100644
--- a/src/cmd/go/internal/modcmd/graph.go
+++ b/src/cmd/go/internal/modcmd/graph.go
@@ -42,7 +42,6 @@ var (
func init() {
cmdGraph.Flag.Var(&graphGo, "go", "")
base.AddModCommonFlags(&cmdGraph.Flag)
- base.AddWorkfileFlag(&cmdGraph.Flag)
}
func runGraph(ctx context.Context, cmd *base.Command, args []string) {
diff --git a/src/cmd/go/internal/modcmd/verify.go b/src/cmd/go/internal/modcmd/verify.go
index 3f0c005d5d..459bf5d070 100644
--- a/src/cmd/go/internal/modcmd/verify.go
+++ b/src/cmd/go/internal/modcmd/verify.go
@@ -39,7 +39,6 @@ See https://golang.org/ref/mod#go-mod-verify for more about 'go mod verify'.
func init() {
base.AddModCommonFlags(&cmdVerify.Flag)
- base.AddWorkfileFlag(&cmdVerify.Flag)
}
func runVerify(ctx context.Context, cmd *base.Command, args []string) {
diff --git a/src/cmd/go/internal/modcmd/why.go b/src/cmd/go/internal/modcmd/why.go
index d8355cca95..2d3f1eb05b 100644
--- a/src/cmd/go/internal/modcmd/why.go
+++ b/src/cmd/go/internal/modcmd/why.go
@@ -59,7 +59,6 @@ var (
func init() {
cmdWhy.Run = runWhy // break init cycle
base.AddModCommonFlags(&cmdWhy.Flag)
- base.AddWorkfileFlag(&cmdWhy.Flag)
}
func runWhy(ctx context.Context, cmd *base.Command, args []string) {
diff --git a/src/cmd/go/internal/modload/init.go b/src/cmd/go/internal/modload/init.go
index 523be8c473..a07066696e 100644
--- a/src/cmd/go/internal/modload/init.go
+++ b/src/cmd/go/internal/modload/init.go
@@ -288,16 +288,16 @@ func BinDir() string {
// operate in workspace mode. It should not be called by other commands,
// for example 'go mod tidy', that don't operate in workspace mode.
func InitWorkfile() {
- switch cfg.WorkFile {
+ switch gowork := cfg.Getenv("GOWORK"); gowork {
case "off":
workFilePath = ""
case "", "auto":
workFilePath = findWorkspaceFile(base.Cwd())
default:
- if !filepath.IsAbs(cfg.WorkFile) {
- base.Fatalf("the path provided to -workfile must be an absolute path")
+ if !filepath.IsAbs(gowork) {
+ base.Fatalf("the path provided to GOWORK must be an absolute path")
}
- workFilePath = cfg.WorkFile
+ workFilePath = gowork
}
}
@@ -1109,7 +1109,7 @@ func setDefaultBuildMod() {
if inWorkspaceMode() && cfg.BuildMod != "readonly" {
base.Fatalf("go: -mod may only be set to readonly when in workspace mode, but it is set to %q"+
"\n\tRemove the -mod flag to use the default readonly value,"+
- "\n\tor set -workfile=off to disable workspace mode.", cfg.BuildMod)
+ "\n\tor set GOWORK=off to disable workspace mode.", cfg.BuildMod)
}
// Don't override an explicit '-mod=' argument.
return
diff --git a/src/cmd/go/internal/run/run.go b/src/cmd/go/internal/run/run.go
index c4b70b64fe..00a3e4b332 100644
--- a/src/cmd/go/internal/run/run.go
+++ b/src/cmd/go/internal/run/run.go
@@ -65,7 +65,6 @@ func init() {
CmdRun.Run = runRun // break init loop
work.AddBuildFlags(CmdRun, work.DefaultBuildFlags)
- base.AddWorkfileFlag(&CmdRun.Flag)
CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
}
diff --git a/src/cmd/go/internal/test/testflag.go b/src/cmd/go/internal/test/testflag.go
index b9d1ec91ff..c046caca25 100644
--- a/src/cmd/go/internal/test/testflag.go
+++ b/src/cmd/go/internal/test/testflag.go
@@ -28,7 +28,6 @@ import (
func init() {
work.AddBuildFlags(CmdTest, work.OmitVFlag)
- base.AddWorkfileFlag(&CmdTest.Flag)
cf := CmdTest.Flag
cf.BoolVar(&testC, "c", false, "")
diff --git a/src/cmd/go/internal/work/build.go b/src/cmd/go/internal/work/build.go
index 1c278d3d99..0b5848a77d 100644
--- a/src/cmd/go/internal/work/build.go
+++ b/src/cmd/go/internal/work/build.go
@@ -130,14 +130,6 @@ and test commands:
directory, but it is not accessed. When -modfile is specified, an
alternate go.sum file is also used: its path is derived from the
-modfile flag by trimming the ".mod" extension and appending ".sum".
- -workfile file
- in module aware mode, use the given go.work file as a workspace file.
- By default or when -workfile is "auto", the go command searches for a
- file named go.work in the current directory and then containing directories
- until one is found. If a valid go.work file is found, the modules
- specified will collectively be used as the main modules. If -workfile
- is "off", or a go.work file is not found in "auto" mode, workspace
- mode is disabled.
-overlay file
read a JSON config file that provides an overlay for build operations.
The file is a JSON struct with a single field, named 'Replace', that
@@ -217,7 +209,6 @@ func init() {
AddBuildFlags(CmdBuild, DefaultBuildFlags)
AddBuildFlags(CmdInstall, DefaultBuildFlags)
- base.AddWorkfileFlag(&CmdBuild.Flag)
}
// Note that flags consulted by other parts of the code
diff --git a/src/cmd/go/internal/workcmd/edit.go b/src/cmd/go/internal/workcmd/edit.go
index e7b1b13271..05f4f3dddf 100644
--- a/src/cmd/go/internal/workcmd/edit.go
+++ b/src/cmd/go/internal/workcmd/edit.go
@@ -110,8 +110,6 @@ func init() {
cmdEdit.Flag.Var(flagFunc(flagEditworkDropUse), "dropuse", "")
cmdEdit.Flag.Var(flagFunc(flagEditworkReplace), "replace", "")
cmdEdit.Flag.Var(flagFunc(flagEditworkDropReplace), "dropreplace", "")
-
- base.AddWorkfileFlag(&cmdEdit.Flag)
}
func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
@@ -137,7 +135,7 @@ func runEditwork(ctx context.Context, cmd *base.Command, args []string) {
}
if gowork == "" {
- base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using -workfile flag)")
+ base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
}
anyFlags :=
diff --git a/src/cmd/go/internal/workcmd/init.go b/src/cmd/go/internal/workcmd/init.go
index aa3126319a..63bee6e4f5 100644
--- a/src/cmd/go/internal/workcmd/init.go
+++ b/src/cmd/go/internal/workcmd/init.go
@@ -33,7 +33,6 @@ current go version will also be listed in the go.work file.
func init() {
base.AddModCommonFlags(&cmdInit.Flag)
- base.AddWorkfileFlag(&cmdInit.Flag)
}
func runInit(ctx context.Context, cmd *base.Command, args []string) {
@@ -41,11 +40,6 @@ func runInit(ctx context.Context, cmd *base.Command, args []string) {
modload.ForceUseModules = true
- // TODO(matloob): support using the -workfile path
- // To do that properly, we'll have to make the module directories
- // make dirs relative to workFile path before adding the paths to
- // the directory entries
-
workFile := modload.WorkFilePath()
if workFile == "" {
workFile = filepath.Join(base.Cwd(), "go.work")
diff --git a/src/cmd/go/internal/workcmd/sync.go b/src/cmd/go/internal/workcmd/sync.go
index 948fc5d370..b0f61c5fa2 100644
--- a/src/cmd/go/internal/workcmd/sync.go
+++ b/src/cmd/go/internal/workcmd/sync.go
@@ -39,14 +39,13 @@ that in each workspace module.
func init() {
base.AddModCommonFlags(&cmdSync.Flag)
- base.AddWorkfileFlag(&cmdSync.Flag)
}
func runSync(ctx context.Context, cmd *base.Command, args []string) {
modload.ForceUseModules = true
modload.InitWorkfile()
if modload.WorkFilePath() == "" {
- base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using -workfile flag)")
+ base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
}
workGraph := modload.LoadModGraph(ctx, "")
diff --git a/src/cmd/go/internal/workcmd/use.go b/src/cmd/go/internal/workcmd/use.go
index 3d003b78eb..1ee2d4e3c4 100644
--- a/src/cmd/go/internal/workcmd/use.go
+++ b/src/cmd/go/internal/workcmd/use.go
@@ -42,7 +42,6 @@ func init() {
cmdUse.Run = runUse // break init cycle
base.AddModCommonFlags(&cmdUse.Flag)
- base.AddWorkfileFlag(&cmdUse.Flag)
}
func runUse(ctx context.Context, cmd *base.Command, args []string) {
@@ -53,7 +52,7 @@ func runUse(ctx context.Context, cmd *base.Command, args []string) {
gowork = modload.WorkFilePath()
if gowork == "" {
- base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using -workfile flag)")
+ base.Fatalf("go: no go.work file found\n\t(run 'go work init' first or specify path using GOWORK environment variable)")
}
workFile, err := modload.ReadWorkFile(gowork)
if err != nil {
diff --git a/src/cmd/go/testdata/script/work.txt b/src/cmd/go/testdata/script/work.txt
index cbb3746a69..a10bf5a1c3 100644
--- a/src/cmd/go/testdata/script/work.txt
+++ b/src/cmd/go/testdata/script/work.txt
@@ -32,7 +32,9 @@ stdout 'example.com/b'
go list -mod=readonly all
! go list -mod=mod all
stderr '^go: -mod may only be set to readonly when in workspace mode'
-go list -mod=mod -workfile=off all
+env GOWORK=off
+go list -mod=mod all
+env GOWORK=
# Test that duplicates in the use list return an error
cp go.work go.work.backup
@@ -53,7 +55,9 @@ go run example.com/d
# This exercises the code that determines which module command-line-arguments
# belongs to.
go list ./b/main.go
-go build -n -workfile=off -o foo foo.go
+env GOWORK=off
+go build -n -o foo foo.go
+env GOWORK=
go build -n -o foo foo.go
-- go.work.dup --
diff --git a/src/cmd/go/testdata/script/work_edit.txt b/src/cmd/go/testdata/script/work_edit.txt
index fd04bbda6e..71959ca0dd 100644
--- a/src/cmd/go/testdata/script/work_edit.txt
+++ b/src/cmd/go/testdata/script/work_edit.txt
@@ -30,7 +30,8 @@ cmp stdout go.work.want_print
go work edit -json -go 1.19 -use b -dropuse c -replace 'x.1@v1.4.0 = ../z' -dropreplace x.1 -dropreplace x.1@v1.3.0
cmp stdout go.work.want_json
-go work edit -print -fmt -workfile $GOPATH/src/unformatted
+env GOWORK=$GOPATH/src/unformatted
+go work edit -print -fmt
cmp stdout formatted
-- m/go.mod --
diff --git a/src/cmd/go/testdata/script/work_env.txt b/src/cmd/go/testdata/script/work_env.txt
index ec3d3be3ed..511bb4e2cb 100644
--- a/src/cmd/go/testdata/script/work_env.txt
+++ b/src/cmd/go/testdata/script/work_env.txt
@@ -13,6 +13,10 @@ cd src
go env GOWORK
stdout 'go.work'
+env GOWORK='off'
+go env GOWORK
+stdout 'off'
+
! go env -w GOWORK=off
stderr '^go: GOWORK cannot be modified$'
diff --git a/src/cmd/go/testdata/script/work_gowork.txt b/src/cmd/go/testdata/script/work_gowork.txt
new file mode 100644
index 0000000000..1cfbf0ca18
--- /dev/null
+++ b/src/cmd/go/testdata/script/work_gowork.txt
@@ -0,0 +1,24 @@
+env GOWORK=stop.work
+! go list a # require absolute path
+! stderr panic
+env GOWORK=doesnotexist
+! go list a
+! stderr panic
+
+env GOWORK=$GOPATH/src/stop.work
+go list -n a
+go build -n a
+go test -n a
+
+-- stop.work --
+go 1.18
+
+use ./a
+-- a/a.go --
+package a
+-- a/a_test.go --
+package a
+-- a/go.mod --
+module a
+
+go 1.18
\ No newline at end of file
diff --git a/src/cmd/go/testdata/script/work_init_workfile.txt b/src/cmd/go/testdata/script/work_init_gowork.txt
similarity index 52%
rename from src/cmd/go/testdata/script/work_init_workfile.txt
rename to src/cmd/go/testdata/script/work_init_gowork.txt
index e6f56716f9..55ac99b8c0 100644
--- a/src/cmd/go/testdata/script/work_init_workfile.txt
+++ b/src/cmd/go/testdata/script/work_init_gowork.txt
@@ -1,11 +1,15 @@
-# Test that the workfile flag is used by go work init.
+# Test that the GOWORK environment variable flag is used by go work init.
+! exists go.work
go work init
exists go.work
-go work init -workfile=$GOPATH/src/foo/foo.work
+env GOWORK=$GOPATH/src/foo/foo.work
+! exists foo/foo.work
+go work init
exists foo/foo.work
+env GOWORK=
cd foo/bar
! go work init
stderr 'already exists'
diff --git a/src/cmd/go/testdata/script/work_nowork.txt b/src/cmd/go/testdata/script/work_nowork.txt
index b0320cbccb..b4c9b1d9cf 100644
--- a/src/cmd/go/testdata/script/work_nowork.txt
+++ b/src/cmd/go/testdata/script/work_nowork.txt
@@ -1,17 +1,17 @@
! go work use
-stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using -workfile flag\)$'
+stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$'
! go work use .
-stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using -workfile flag\)$'
+stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$'
! go work edit
-stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using -workfile flag\)$'
+stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$'
! go work edit -go=1.18
-stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using -workfile flag\)$'
+stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$'
! go work sync
-stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using -workfile flag\)$'
+stderr '^go: no go\.work file found\n\t\(run ''go work init'' first or specify path using GOWORK environment variable\)$'
-- go.mod --
module example
diff --git a/src/cmd/go/testdata/script/work_workfile.txt b/src/cmd/go/testdata/script/work_workfile.txt
deleted file mode 100644
index b62918147e..0000000000
--- a/src/cmd/go/testdata/script/work_workfile.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-! go list -workfile=stop.work a # require absolute path
-! stderr panic
-! go list -workfile=doesnotexist a
-! stderr panic
-
-go list -n -workfile=$GOPATH/src/stop.work a
-go build -n -workfile=$GOPATH/src/stop.work a
-go test -n -workfile=$GOPATH/src/stop.work a
-
--- stop.work --
-go 1.18
-
-use ./a
--- a/a.go --
-package a
--- a/a_test.go --
-package a
--- a/go.mod --
-module a
-
-go 1.18
\ No newline at end of file
diff --git a/src/internal/cfg/cfg.go b/src/internal/cfg/cfg.go
index 4cb3fbd4f3..78664d7a96 100644
--- a/src/internal/cfg/cfg.go
+++ b/src/internal/cfg/cfg.go
@@ -62,6 +62,7 @@ const KnownEnv = `
GOTOOLDIR
GOVCS
GOWASM
+ GOWORK
GO_EXTLINK_ENABLED
PKG_CONFIG
`
From f985833dec19b0147db3c5c33d3bf0181891d458 Mon Sep 17 00:00:00 2001
From: "Bryan C. Mills" Go command
+
+
go getgo get no longer builds or installs packages in
module-aware mode. go get is now dedicated to
@@ -269,6 +271,8 @@ Do not send CLs removing the interior tags from such phrases.
and installs packages, as before.
+
go versiongo command now embeds version control information in
binaries including the currently checked-out revision, commit time, and a
@@ -303,6 +307,8 @@ Do not send CLs removing the interior tags from such phrases.
debug/buildinfo package from go 1.18+.
+
go mod downloadgo.mod file
specifies go 1.17
@@ -316,6 +322,8 @@ Do not send CLs removing the interior tags from such phrases.
go mod download all.
+
go mod vendorgo mod vendor subcommand now
supports a -o flag to set the output directory.
@@ -325,6 +333,8 @@ Do not send CLs removing the interior tags from such phrases.
third-party tools that need to collect package source code.)
+
go build -asango build command and related commands
now support an -asan flag that enables interoperation
@@ -332,6 +342,8 @@ Do not send CLs removing the interior tags from such phrases.
option -fsanitize=address).
+
go mod tidygo mod tidy command now retains
additional checksums in the go.sum file for modules whose source
@@ -342,6 +354,8 @@ Do not send CLs removing the interior tags from such phrases.
module's go.mod file.
+
go workgo command now supports a "Workspace" mode. If a
go.work file is found in the working directory or a
@@ -355,6 +369,8 @@ Do not send CLs removing the interior tags from such phrases.
documentation.
+
go testgo command now supports additional command line
options for the new fuzzing support described
@@ -376,11 +392,28 @@ Do not send CLs removing the interior tags from such phrases.
+
//go:build lines//go:build lines as a more readable way to write build constraints,
+instead of // +build lines.
+As of Go 1.17, gofmt adds //go:build lines
+to match existing +build lines and keeps them in sync,
+while go vet diagnoses when they are out of sync.
+gofmt//go:build lines.
+In Go 1.18, go fix now removes the now-obsolete
+// +build lines in modules declaring
+go 1.17 or later in their go.mod files.
+Gofmt
gofmt now reads and formats input files concurrently, with a
@@ -388,7 +421,7 @@ Do not send CLs removing the interior tags from such phrases.
multiple CPUs, gofmt should now be significantly faster.
+vetVet
Updates for Generics
@@ -510,10 +543,17 @@ Do not send CLs removing the interior tags from such phrases.
new go command -asan option.
- TODO: https://golang.org/cl/369914: for default bootstrap, use Go 1.17 if present, falling back to Go 1.4
+When building a Go release from source and GOROOT_BOOTSTRAP
+is not set, previous versions of Go looked for a Go 1.4 or later bootstrap toolchain
+in the directory $HOME/go1.4 (%HOMEDRIVE%%HOMEPATH%\go1.4 on Windows).
+Go now looks first for $HOME/go1.17 or $HOME/sdk/go1.17
+before falling back to $HOME/go1.4.
+We intend for Go 1.19 to require Go 1.17 or later for bootstrap,
+and this change should make the transition smoother.
+For more details, see go.dev/issue/44505.
comparable is an interface the denotes the set of all types which can be
+ comparable is an interface that denotes the set of all types which can be
compared using == or !=. It may only be used as (or embedded in)
a type constraint.
The go command now embeds version control information in
- binaries including the currently checked-out revision, commit time, and a
+ binaries. It includes the currently checked-out revision, commit time, and a
flag indicating whether edited or untracked files are present. Version
control information is embedded if the go command is invoked in
a directory within a Git, Mercurial, Fossil, or Bazaar repository, and the
@@ -285,7 +285,7 @@ Do not send CLs removing the interior tags from such phrases.
- Additionally, the go command embeds information about the build
+ Additionally, the go command embeds information about the build,
including build and tool tags (set with -tags), compiler,
assembler, and linker flags (like -gcflags), whether cgo was
enabled, and if it was, the values of the cgo environment variables
@@ -509,7 +509,7 @@ For more information, see https://
- The new compiler -asan option supports the
+ The new -asan compiler option supports the
new go command -asan option.
- The new linker -asan option supports the
+ The new -asan linker option supports the
new go command -asan option.
- The methods Reader.Reset and
- Writer.Reset
+ The Reader.Reset and
+ Writer.Reset methods
now use the default buffer size when called on objects with a
nil buffer.
- User.GroupIds.
+ User.GroupIds
now uses a Go native implementation when cgo is not available.
Value.SetIterKey
and Value.SetIterValue
methods set a Value using a map iterator as the source. They are equivalent to
- Value.Set(iter.Key()) and Value.Set(iter.Value()) but
+ Value.Set(iter.Key()) and Value.Set(iter.Value()), but
do fewer allocations.
@@ -1219,7 +1219,7 @@ For more details, see go.dev/issue/44505
- Wrapper interface has been removed.
+ The Wrapper interface has been removed.
- The AppendRune function appends the UTF-8 new
+ The new AppendRune function appends the UTF-8
encoding of a rune to a []byte.
go build -asan
- The go build command and related commands
- now support an -asan flag that enables interoperation
- with C (or C++) code compiled with the address sanitizer (C compiler
- option -fsanitize=address).
-
go mod tidy@@ -369,6 +360,15 @@ Do not send CLs removing the interior tags from such phrases. documentation.
+go build -asan
+ The go build command and related commands
+ now support an -asan flag that enables interoperation
+ with C (or C++) code compiled with the address sanitizer (C compiler
+ option -fsanitize=address).
+
go test
From 35170365c83085024e4855c14032599f5513d563 Mon Sep 17 00:00:00 2001
From: Martin Sucha
-
Go 1.18 introduces the new
+ The CPU profiler now uses per-thread timers on Linux. This increases the
+ maximum CPU usage that a profile can observe, and reduces some forms of
+ bias.
+
From 4edefe95689c31846a73e36b3e0723c924def45d Mon Sep 17 00:00:00 2001
From: Dan Scales
+ Go 1.18 requires Linux kernel version 2.6.32 or later.
+
From 55e5b03cb359c591a2ca6ad8b6e9274d094b1632 Mon Sep 17 00:00:00 2001
From: "Bryan C. Mills"
+ The
From 7c694fbad1ed6f2f825fd09cf7a86da3be549cea Mon Sep 17 00:00:00 2001
From: Robert Griesemer SysProcAttr.Pdeathsig.
+ SysProcAttr.Pdeathsig
is now supported in FreeBSD.
GOAMD64 environment variable, which selects at compile time
- a mininum target version of the AMD64 architecture. Allowed values are v1,
+ a minimum target version of the AMD64 architecture. Allowed values are v1,
v2, v3, or v4. Each higher level requires,
and takes advantage of, additional processor features. A detailed
description can be found
From 8c5904f149a4863183925c71ce4118413e7e0167 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20Geisend=C3=B6rfer?=
+
real, imag, and complex.
We hope to remove this restriction in Go 1.19.
+ m on a value
+ x of type parameter type P if m is explictly
+ declared by P's constraint interface.
+ Similarly, method values x.m and method expressions
+ P.m also are only supported if m is explicitly
+ declared by P, even though m might be in the method set
+ of P by virtue of the fact that all types in P implement
+ m. We hope to remove this restriction in Go 1.19.
+ c-archive and c-shared build modes.
Linux
+
+Windows
Automatic
+
+go.mod and go.sum updatesgo mod graph,
+ go mod vendor,
+ go mod verify, and
+ go mod why subcommands
+ no longer automatically update the go.mod and
+ go.sum files.
+ (Those files can be updated explicitly using go get,
+ go mod tidy, or
+ go mod download.)
+go version