From 00aa4dddab2c05382b13364b0ed3215ee599366f Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 1 Jul 2022 00:11:29 +0000 Subject: [PATCH 01/22] Checkpoint progress. --- docs/design/README.md | 57 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/docs/design/README.md b/docs/design/README.md index 2ca7692308e69..19117dfadc7a9 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -24,6 +24,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Floating-point literals](#floating-point-literals) - [String types](#string-types) - [String literals](#string-literals) +- [Value categories](#value-categories) - [Composite types](#composite-types) - [Tuples](#tuples) - [Struct types](#struct-types) @@ -40,6 +41,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Variable `var` declarations](#variable-var-declarations) - [`auto`](#auto) - [Functions](#functions) + - [Parameters](#parameters) - [`auto` return type](#auto-return-type) - [Blocks and statements](#blocks-and-statements) - [Assignment statements](#assignment-statements) @@ -61,6 +63,11 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Inheritance](#inheritance) - [Access control](#access-control) - [Destructors](#destructors) + - [Unformed state](#unformed-state) + - [Move](#move) + - [Argument passing](#argument-passing) + - [Copyable types](#copyable-types) + - [Move-only types](#move-only-types) - [Choice types](#choice-types) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) @@ -376,6 +383,10 @@ are available for representing strings with `\`s and `"`s. > - Proposal > [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) +## Value categories + +FIXME + ## Composite types ### Tuples @@ -529,6 +540,7 @@ Some common expressions in Carbon include: - [Indexing](#arrays-and-slices): `a[3]` - [Function](#functions) call: `f(4)` - [Pointer](#pointer-types): `*p`, `p->m`, `&x` + - FIXME: Move: `~x` - [Conditionals](expressions/if.md): `if c then t else f` - Parentheses: `(7 + 8) * (3 - 1)` @@ -790,6 +802,10 @@ that any mutations will not be visible to the caller. > - Question-for-leads issue > [#476: Optional argument names (unused arguments)](https://github.com/carbon-language/carbon-lang/issues/476) +### Parameters + +FIXME + ### `auto` return type If `auto` is used in place of the return type, the return type of the function @@ -1475,6 +1491,39 @@ type, use `UnsafeDelete`. > - Proposal > [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) +#### Unformed state + +FIXME + +#### Move + +FIXME + +#### Argument passing + +##### Copyable types + +For types that are copyable and movable: + +| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | +| ------------ | ---------------------- | ------------------------ | ---------------------- | +| `a.M()` | copy or const-ref | by address | copy | +| `GetA().M()` | move or const-ref | error | copy or move | +| `(~a).M()` | move or move+const-ref | error | move | + +Note that this last column would be unusual. Pass as the argument in a function +call is the same, but without the `addr` column. + +##### Move-only types + +For types that are movable but non-copyable: + +| Call | `fn M[me: Self]() | fn M[addr me: Self\*]()` | `fn M[var me: Self]()` | +| ------------ | ---------------------- | ------------------------ | ---------------------- | +| `a.M()` | const-ref | by address | error | +| `GetA().M()` | move or const-ref | error | move | +| `(~a).M()` | move or move+const-ref | error | move | + ### Choice types A _choice type_ is a [tagged union](https://en.wikipedia.org/wiki/Tagged_union), @@ -2201,6 +2250,14 @@ The interfaces that correspond to each operator are given by: The [logical operators can not be overloaded](expressions/logical_operators.md#overloading). +Operators that result in l-values, such as dereferencing `*p` and indexing +`a[3]`, have interfaces that return the address of the value. Carbon +automatically dereferences the pointer to get the l-value. + +Operators that can take multiple arguments, such as function calling operator +`f(4)`, have a [variadic](generics/details.md#variadic-arguments) parameter +list. + > References: > > - [Operator overloading](generics/details.md#operator-overloading) From c66e86ac75695960fc8f4c509068a18422bf4d9b Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 1 Jul 2022 00:13:41 +0000 Subject: [PATCH 02/22] Checkpoint progress. --- docs/design/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index 19117dfadc7a9..1c18ff827a0cc 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1518,7 +1518,7 @@ call is the same, but without the `addr` column. For types that are movable but non-copyable: -| Call | `fn M[me: Self]() | fn M[addr me: Self\*]()` | `fn M[var me: Self]()` | +| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | | ------------ | ---------------------- | ------------------------ | ---------------------- | | `a.M()` | const-ref | by address | error | | `GetA().M()` | move or const-ref | error | move | From 2bde0bc133f4bed9865f217bf7c30d50d024955e Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 1 Jul 2022 19:43:53 +0000 Subject: [PATCH 03/22] const --- docs/design/README.md | 66 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 1c18ff827a0cc..41c241e5f4531 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -63,6 +63,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Inheritance](#inheritance) - [Access control](#access-control) - [Destructors](#destructors) + - [`const`](#const) - [Unformed state](#unformed-state) - [Move](#move) - [Argument passing](#argument-passing) @@ -766,8 +767,8 @@ Breaking this apart: - `fn` is the keyword used to introduce a function. - Its name is `Add`. This is the name added to the enclosing [scope](#declarations-definitions-and-scopes). -- The parameter list in parentheses (`(`...`)`) is a comma-separated list of - [irrefutable patterns](#patterns). +- The [parameter list](#parameters) in parentheses (`(`...`)`) is a + comma-separated list of [irrefutable patterns](#patterns). - It returns an `i64` result. Functions that return nothing omit the `->` and return type. @@ -785,13 +786,6 @@ fn Add(a: i64, b: i64) -> i64 { The names of the parameters are in scope until the end of the definition or declaration. -The bindings in the parameter list default to -[`let` bindings](#binding-patterns), and so the parameter names are treated as -[r-values](). If -the `var` keyword is added before the binding, then the arguments will be copied -to new storage, and so can be mutated in the function body. The copy ensures -that any mutations will not be visible to the caller. - > References: > > - [Functions](functions.md) @@ -806,6 +800,13 @@ that any mutations will not be visible to the caller. FIXME +The bindings in the parameter list default to +[`let` bindings](#binding-patterns), and so the parameter names are treated as +[r-values](). If +the `var` keyword is added before the binding, then the arguments will be copied +to new storage, and so can be mutated in the function body. The copy ensures +that any mutations will not be visible to the caller. + ### `auto` return type If `auto` is used in place of the return type, the return type of the function @@ -1287,14 +1288,14 @@ class Point { var dy: i32 = y2 - me.y; return Math.Sqrt(dx * dx - dy * dy); } - // Mutating method + // Mutating method declaration fn Offset[addr me: Self*](dx: i32, dy: i32); var x: i32; var y: i32; } -// Out-of-line definition of method declared inline. +// Out-of-line definition of method declared inline fn Point.Offset[addr me: Self*](dx: i32, dy: i32) { me->x += dx; me->y += dy; @@ -1318,7 +1319,9 @@ two methods `Distance` and `Offset`: modifying the `Point`. This is signified using `[me: Self]` in the method declaration. - `origin.Offset(`...`)` does modify the value of `origin`. This is signified - using `[addr me: Self*]` in the method declaration. + using `[addr me: Self*]` in the method declaration. Since calling this + method requires taking the address of `origin`, it may only be called on + [non-`const`](#const) l-values. - Methods may be declared lexically inline like `Distance`, or lexically out of line like `Offset`. @@ -1491,6 +1494,45 @@ type, use `UnsafeDelete`. > - Proposal > [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) +#### `const` + +For every type `MyClass`, there is the type `const MyClass` such that: + +- The data representation is the same, so a `MyClass*` value may be implicitly + converted to a `(const MyClass)*`. +- A `const MyClass` l-value may automatically convert to a `MyClass` r-value, + the same way that a `MyClass` l-value can. +- If member `x` of `MyClass` has type `T`, then member `x` of `const MyClass` + has type `const T`. +- The API of a `const MyClass` is a subset of `MyClass`, excluding all methods + taking `[addr me: Self*]`. + +Note that `const` binds more tightly than postfix-`*` for forming a pointer +type, so `const MyClass*` is equal to `(const MyClass)*`. + +This example uses the definition of `Point` from the +["methods" section](#methods): + +```carbon +var origin: Point = {.x = 0, .y = 0}; + +// ✅ Allowed conversion from `Point*` to +// `const Point*`: +let p: const Point* = &origin; + +// ✅ Allowed conversion of `const Point` l-value +// to `Point` r-value. +let five: f32 = p->Distance(3, 4); + +// ❌ Error: mutating method `Offset` excluded +// from `const Point` API. +p->Offset(3, 4); + +// ❌ Error: mutating method `AssignAdd.Op` +// excluded from `const i32` API. +p->x += 2; +``` + #### Unformed state FIXME From 3a89ea55f3b5a907f7c9d6ad55d65f8633dac708 Mon Sep 17 00:00:00 2001 From: Josh L Date: Sun, 3 Jul 2022 20:06:29 +0000 Subject: [PATCH 04/22] Checkpoint progress. --- docs/design/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/design/README.md b/docs/design/README.md index 41c241e5f4531..68659925ae808 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -388,6 +388,26 @@ are available for representing strings with `\`s and `"`s. FIXME +- L-values: have storage and a stable address. May be modified, assuming type + is not [`const`](#const). +- R-values: no dedicated storage, may be stored in registers, may not take the + address, may not be modified, may be silently copied, may silently be a + const reference. +- Constant: when the value is known at type-checking time. Examples: literals, + expressions in terns of constants, values of `template` parameters (FIXME: + link). +- Erased constant: checked generics (FIXME: link), the value is known at + compile-time, but not type-checking time. + +Automatic conversions + +```mermaid + graph TD; + Erased constant-->Constant; + Constant-->R-value; + L-value-->R-value; +``` + ## Composite types ### Tuples From 2d9ac3febf621dab90f3d964b8868a8a631da795 Mon Sep 17 00:00:00 2001 From: Josh L Date: Sun, 3 Jul 2022 20:12:11 +0000 Subject: [PATCH 05/22] Checkpoint progress. --- docs/design/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 68659925ae808..d8bd5b0e21bf9 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -402,10 +402,9 @@ FIXME Automatic conversions ```mermaid - graph TD; - Erased constant-->Constant; - Constant-->R-value; - L-value-->R-value; +graph TD; + A(Erased constant)-->B(Constant)-->C(R-value); + D(L-value)-->C; ``` ## Composite types From bca152e0da9d823aba8f77dd882c15ce2b207e15 Mon Sep 17 00:00:00 2001 From: Josh L Date: Sun, 3 Jul 2022 20:18:08 +0000 Subject: [PATCH 06/22] Checkpoint progress. --- docs/design/README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index d8bd5b0e21bf9..5042dcb8f0ce3 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -393,17 +393,19 @@ FIXME - R-values: no dedicated storage, may be stored in registers, may not take the address, may not be modified, may be silently copied, may silently be a const reference. -- Constant: when the value is known at type-checking time. Examples: literals, - expressions in terns of constants, values of `template` parameters (FIXME: - link). -- Erased constant: checked generics (FIXME: link), the value is known at - compile-time, but not type-checking time. +- Constant: when the value is known at type-checking time. Examples: literals + ([integer](#integer-literals), [floating-point](#floating-point-literals), + [string](#string-literals)), expressions in terns of constants, values of + [`template` parameters](#checked-and-template-parameters). +- Erased constant: [checked generics](#checked-and-template-parameters), the + value is known at compile-time, but not type-checking time. -Automatic conversions +Carbon will automatically convert from a constant to an erased constant, or from +any value category to R-value: ```mermaid graph TD; - A(Erased constant)-->B(Constant)-->C(R-value); + A(Constant)-->B(Erased constant)-->C(R-value); D(L-value)-->C; ``` From 4233a048d694bf8a7e877752e3e351d7a4df477f Mon Sep 17 00:00:00 2001 From: Josh L Date: Sun, 3 Jul 2022 23:27:11 +0000 Subject: [PATCH 07/22] Checkpoint progress. --- docs/design/README.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/design/README.md b/docs/design/README.md index 5042dcb8f0ce3..f7fc0a44c2dd0 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -69,6 +69,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Argument passing](#argument-passing) - [Copyable types](#copyable-types) - [Move-only types](#move-only-types) + - [Unmovable types](#unmovable-types) - [Choice types](#choice-types) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) @@ -1564,6 +1565,11 @@ FIXME #### Argument passing +```carbon +var a: AType; +fn GetA() -> AType; +``` + ##### Copyable types For types that are copyable and movable: @@ -1587,6 +1593,16 @@ For types that are movable but non-copyable: | `GetA().M()` | move or const-ref | error | move | | `(~a).M()` | move or move+const-ref | error | move | +##### Unmovable types + +For types that are neither movable nor copyable: + +| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | +| ------------ | ------------------ | ------------------------ | ---------------------- | +| `a.M()` | const-ref | by address | error | +| `GetA().M()` | const-ref | error | error | +| `(~a).M()` | error | error | error | + ### Choice types A _choice type_ is a [tagged union](https://en.wikipedia.org/wiki/Tagged_union), From c7589c8ef7d4bff484c0f78aef4170f2cd1a9eeb Mon Sep 17 00:00:00 2001 From: Josh L Date: Tue, 5 Jul 2022 16:32:35 +0000 Subject: [PATCH 08/22] Checkpoint progress. --- docs/design/README.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index f7fc0a44c2dd0..3a33eaf0b71e3 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1572,20 +1572,23 @@ fn GetA() -> AType; ##### Copyable types -For types that are copyable and movable: +For types that are copyable and movable, like [integer](#integer-types) and +[floating-point](#floating-point-types) types: -| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | -| ------------ | ---------------------- | ------------------------ | ---------------------- | -| `a.M()` | copy or const-ref | by address | copy | -| `GetA().M()` | move or const-ref | error | copy or move | -| `(~a).M()` | move or move+const-ref | error | move | +| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | +| ------------ | ------------------------- | ------------------------ | ---------------------- | +| `a.M()` | copy or const-ref | by address | copy | +| `GetA().M()` | copy or move or const-ref | error | copy or move | +| `(~a).M()` | move or move+const-ref | error | move | Note that this last column would be unusual. Pass as the argument in a function call is the same, but without the `addr` column. ##### Move-only types -For types that are movable but non-copyable: +For types that are movable but non-copyable, like types representing resources, +such as `Box(T)` (Carbon's equivalent of +[C++'s `std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr)): | Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | | ------------ | ---------------------- | ------------------------ | ---------------------- | @@ -1595,7 +1598,7 @@ For types that are movable but non-copyable: ##### Unmovable types -For types that are neither movable nor copyable: +For types that are neither movable nor copyable, like `Mutex`: | Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | | ------------ | ------------------ | ------------------------ | ---------------------- | From eb01e4edf72d15c9a09ad33b4f0258289e2ce2b6 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 7 Jul 2022 21:56:02 +0000 Subject: [PATCH 09/22] Unformed --- docs/design/README.md | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 3a33eaf0b71e3..53068cc5add9f 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -645,7 +645,8 @@ Binding patterns default to _`let` bindings_ except inside a context where the - The result of a `let` binding is the name is bound to an [non-l-value](). - This means the value can not be modified, and its address cannot be taken. + This means the value can not be modified, and its address generally cannot + be taken. - A `var` binding has dedicated storage, and so the name is an [l-value]() which can be modified and has a stable address. @@ -738,10 +739,9 @@ var x: i64 = 42; x = 7; ``` -Variables with a type that has -[an unformed state](https://github.com/carbon-language/carbon-lang/pull/257) do -not need to be initialized in the variable declaration, but do need to be -assigned before they are used. +Variables with a type that has [an unformed state](#unformed-state) do not need +to be initialized in the variable declaration, but do need to be assigned before +they are used. > References: > @@ -1557,7 +1557,33 @@ p->x += 2; #### Unformed state -FIXME +Types indicate that they support unformed states by +[implementing an interface](#interfaces-and-implementations), otherwise +variables of that type must be explicitly initialized when they are declared. + +An unformed state for an object is one that satisfies the following properties: + +- Assignment from a fully formed value is correct using the normal assignment + implementation for the type. +- Destruction must be correct using the type's normal destruction + implementation. +- Destruction must be optional. The behavior of the program must be equivalent + whether the destructor is run or not for an unformed object, including not + leaking resources. + +A type might have more than one in-memory representation for the unformed state, +and those representations may be the same as valid fully formed values for that +type. For example, all values are legal representations of the unformed state +for any type with a trivial destructor like `i32`. + +Any operation on an unformed object _other_ than destruction or assignment to a +fully formed value is an error, even if its in-memory representation is that of +a valid value for that type. + +> References: +> +> - Proposal +> [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257) #### Move From f3c2a2a79787932b7f5c31e3b9395e9df98c255f Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 7 Jul 2022 23:04:09 +0000 Subject: [PATCH 10/22] Add move remove argument passing --- docs/design/README.md | 54 ++++--------------------------------------- 1 file changed, 5 insertions(+), 49 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 53068cc5add9f..64d210e8c8606 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -66,10 +66,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [`const`](#const) - [Unformed state](#unformed-state) - [Move](#move) - - [Argument passing](#argument-passing) - - [Copyable types](#copyable-types) - - [Move-only types](#move-only-types) - - [Unmovable types](#unmovable-types) - [Choice types](#choice-types) - [Names](#names) - [Packages, libraries, namespaces](#packages-libraries-namespaces) @@ -563,7 +559,7 @@ Some common expressions in Carbon include: - [Indexing](#arrays-and-slices): `a[3]` - [Function](#functions) call: `f(4)` - [Pointer](#pointer-types): `*p`, `p->m`, `&x` - - FIXME: Move: `~x` + - [Move](#move): `~x` - [Conditionals](expressions/if.md): `if c then t else f` - Parentheses: `(7 + 8) * (3 - 1)` @@ -1587,50 +1583,10 @@ a valid value for that type. #### Move -FIXME - -#### Argument passing - -```carbon -var a: AType; -fn GetA() -> AType; -``` - -##### Copyable types - -For types that are copyable and movable, like [integer](#integer-types) and -[floating-point](#floating-point-types) types: - -| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | -| ------------ | ------------------------- | ------------------------ | ---------------------- | -| `a.M()` | copy or const-ref | by address | copy | -| `GetA().M()` | copy or move or const-ref | error | copy or move | -| `(~a).M()` | move or move+const-ref | error | move | - -Note that this last column would be unusual. Pass as the argument in a function -call is the same, but without the `addr` column. - -##### Move-only types - -For types that are movable but non-copyable, like types representing resources, -such as `Box(T)` (Carbon's equivalent of -[C++'s `std::unique_ptr`](https://en.cppreference.com/w/cpp/memory/unique_ptr)): - -| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | -| ------------ | ---------------------- | ------------------------ | ---------------------- | -| `a.M()` | const-ref | by address | error | -| `GetA().M()` | move or const-ref | error | move | -| `(~a).M()` | move or move+const-ref | error | move | - -##### Unmovable types - -For types that are neither movable nor copyable, like `Mutex`: - -| Call | `fn M[me: Self]()` | `fn M[addr me: Self*]()` | `fn M[var me: Self]()` | -| ------------ | ------------------ | ------------------------ | ---------------------- | -| `a.M()` | const-ref | by address | error | -| `GetA().M()` | const-ref | error | error | -| `(~a).M()` | error | error | error | +Carbon will allow types to define if and how they are moved. This can happen +when returning a value from a function or by using the _move operator_ `~x`. +This leaves `x` in an [unformed state](#unformed-state) and returns its old +value. ### Choice types From a99921a038663aeffbcd1a8586f969cc4267dd6b Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 8 Jul 2022 05:06:46 +0000 Subject: [PATCH 11/22] Checkpoint progress. --- docs/design/README.md | 109 +++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 44 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 64d210e8c8606..e72ba9fbdcd61 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -24,7 +24,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception - [Floating-point literals](#floating-point-literals) - [String types](#string-types) - [String literals](#string-literals) -- [Value categories](#value-categories) +- [Value categories and value phases](#value-categories-and-value-phases) - [Composite types](#composite-types) - [Tuples](#tuples) - [Struct types](#struct-types) @@ -381,29 +381,41 @@ are available for representing strings with `\`s and `"`s. > - Proposal > [#199: String literals](https://github.com/carbon-language/carbon-lang/pull/199) -## Value categories +## Value categories and value phases -FIXME +FIXME: +[wikipedia]() + +Values are either _l-values_ or _r-values_. Carbon will automatically convert an +l-value to an r-value, but not in the other direction. + +L-values have storage and a stable address. They may be modified, assuming their +type is not [`const`](#const). + +R-values may not have dedicated storage. This means they can not be modified and +their address generally cannot be taken. R-values are broken down into three +kinds, called _value phases_: -- L-values: have storage and a stable address. May be modified, assuming type - is not [`const`](#const). -- R-values: no dedicated storage, may be stored in registers, may not take the - address, may not be modified, may be silently copied, may silently be a - const reference. -- Constant: when the value is known at type-checking time. Examples: literals - ([integer](#integer-literals), [floating-point](#floating-point-literals), - [string](#string-literals)), expressions in terns of constants, values of +- A _constant_ has value known at compile time, and that value is available + during type checking, for example to use as the size of an array. These + include literals ([integer](#integer-literals), + [floating-point](#floating-point-literals), [string](#string-literals)), + expressions in terms of constants, and values of [`template` parameters](#checked-and-template-parameters). -- Erased constant: [checked generics](#checked-and-template-parameters), the - value is known at compile-time, but not type-checking time. +- A _symbolic value_ has a value that will be known at the code generation + stage of compilation when + [monomorphization](https://en.wikipedia.org/wiki/Monomorphization) happens, + but is not known during type checking. This includes + [checked generic parameters](#checked-and-template-parameters). +- A _runtime value_ has a dynamic value only known at runtime. -Carbon will automatically convert from a constant to an erased constant, or from -any value category to R-value: +Carbon will automatically convert a constant to a symbolic value, or any value +to a runtime value: ```mermaid graph TD; - A(Constant)-->B(Erased constant)-->C(R-value); - D(L-value)-->C; + A(constant)-->B(symbolic value)-->C(runtime value); + D(l-value)-->C; ``` ## Composite types @@ -479,11 +491,10 @@ not support the only pointer [operations](#expressions) are: - Dereference: given a pointer `p`, `*p` gives the value `p` points to as an - [l-value](). - `p->m` is syntactic sugar for `(*p).m`. -- Address-of: given an - [l-value]() - `x`, `&x` returns a pointer to `x`. + [l-value](#value-categories-and-value-phases). `p->m` is syntactic sugar for + `(*p).m`. +- Address-of: given an [l-value](#value-categories-and-value-phases) `x`, `&x` + returns a pointer to `x`. There are no [null pointers](https://en.wikipedia.org/wiki/Null_pointer) in Carbon. To represent a pointer that may not refer to a valid object, use the @@ -636,19 +647,25 @@ name. It can only match values that may be underscore (`_`) may be used instead of the name to match a value but without binding any name to it. -Binding patterns default to _`let` bindings_ except inside a context where the -`var` keyword is used to make it a _`var` binding_: +Binding patterns default to _`let` bindings_. The `var` keyword is used to make +it a _`var` binding_. - The result of a `let` binding is the name is bound to an - [non-l-value](). - This means the value can not be modified, and its address generally cannot - be taken. + [r-value](#value-categories-and-value-phases). This means the value can not + be modified, and its address generally cannot be taken. - A `var` binding has dedicated storage, and so the name is an - [l-value]() - which can be modified and has a stable address. + [l-value](#value-categories-and-value-phases) which can be modified and has + a stable address. + +FIXME: have to be a const-reference or copy; which one must not be observable to +the programmer + +FIXME: aspects of the type can determine whether to copy, for example a type +that is not copyable will always use a const-reference A [generic binding](#checked-and-template-parameters) uses `:!` instead of a -colon (`:`) and can only match compile-time values. +colon (`:`) and can only match compile-time values, either a +[constant or symbolic value](#value-categories-and-value-phases). The keyword `auto` may be used in place of the type in a binding pattern, as long as the type can be deduced from the type of a value in the same @@ -727,8 +744,8 @@ introduced into the enclosing [scope](#declarations-definitions-and-scopes). ### Variable `var` declarations A `var` declaration is similar, except with `var` bindings, so `x` here is an -[l-value]() with -storage and an address, and so may be modified: +[l-value](#value-categories-and-value-phases) with storage and an address, and +so may be modified: ```carbon var x: i64 = 42; @@ -820,10 +837,10 @@ FIXME The bindings in the parameter list default to [`let` bindings](#binding-patterns), and so the parameter names are treated as -[r-values](). If -the `var` keyword is added before the binding, then the arguments will be copied -to new storage, and so can be mutated in the function body. The copy ensures -that any mutations will not be visible to the caller. +[r-values](#value-categories-and-value-phases). If the `var` keyword is added +before the binding, then the arguments will be copied to new storage, and so can +be mutated in the function body. The copy ensures that any mutations will not be +visible to the caller. ### `auto` return type @@ -882,8 +899,8 @@ fn Foo() { ### Assignment statements Assignment statements mutate the value of the -[l-value]() -described on the left-hand side of the assignment. +[l-value](#value-categories-and-value-phases) described on the left-hand side of +the assignment. - Assignment: `x = y;`. `x` is assigned the value of `y`. - Increment and decrement: `++i;`, `--j;`. `i` is set to `i + 1`, `j` is set @@ -1339,7 +1356,7 @@ two methods `Distance` and `Offset`: - `origin.Offset(`...`)` does modify the value of `origin`. This is signified using `[addr me: Self*]` in the method declaration. Since calling this method requires taking the address of `origin`, it may only be called on - [non-`const`](#const) l-values. + [non-`const`](#const) [l-values](#value-categories-and-value-phases). - Methods may be declared lexically inline like `Distance`, or lexically out of line like `Offset`. @@ -1518,8 +1535,9 @@ For every type `MyClass`, there is the type `const MyClass` such that: - The data representation is the same, so a `MyClass*` value may be implicitly converted to a `(const MyClass)*`. -- A `const MyClass` l-value may automatically convert to a `MyClass` r-value, - the same way that a `MyClass` l-value can. +- A `const MyClass` [l-value](#value-categories-and-value-phases) may + automatically convert to a `MyClass` r-value, the same way that a `MyClass` + l-value can. - If member `x` of `MyClass` has type `T`, then member `x` of `const MyClass` has type `const T`. - The API of a `const MyClass` is a subset of `MyClass`, excluding all methods @@ -2314,14 +2332,17 @@ The interfaces that correspond to each operator are given by: The [logical operators can not be overloaded](expressions/logical_operators.md#overloading). -Operators that result in l-values, such as dereferencing `*p` and indexing -`a[3]`, have interfaces that return the address of the value. Carbon -automatically dereferences the pointer to get the l-value. +Operators that result in [l-values](#value-categories-and-value-phases), such as +dereferencing `*p` and indexing `a[3]`, have interfaces that return the address +of the value. Carbon automatically dereferences the pointer to get the l-value. Operators that can take multiple arguments, such as function calling operator `f(4)`, have a [variadic](generics/details.md#variadic-arguments) parameter list. +FIXME: Other operations on types not associated with operators like copy, move, +unformed, swap, etc. + > References: > > - [Operator overloading](generics/details.md#operator-overloading) From 9398c13bda16e51a717236f25625b664eb1bd11f Mon Sep 17 00:00:00 2001 From: Josh L Date: Sat, 9 Jul 2022 14:32:15 +0000 Subject: [PATCH 12/22] More examples --- docs/design/README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 05dbfbc9c1475..d819d3a75d00d 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -393,6 +393,10 @@ are available for representing strings with `\`s and `"`s. FIXME: [wikipedia]() +[cppreference](https://en.cppreference.com/w/cpp/language/value_category) + +**FIXME:** Should this be moved together with +[Types are values](#types-are-values)? Values are either _l-values_ or _r-values_. Carbon will automatically convert an l-value to an r-value, but not in the other direction. @@ -408,13 +412,15 @@ kinds, called _value phases_: during type checking, for example to use as the size of an array. These include literals ([integer](#integer-literals), [floating-point](#floating-point-literals), [string](#string-literals)), - expressions in terms of constants, and values of + concrete type values (like `f64` or `Optional(i32*)`), expressions in terms + of constants, and values of [`template` parameters](#checked-and-template-parameters). - A _symbolic value_ has a value that will be known at the code generation stage of compilation when [monomorphization](https://en.wikipedia.org/wiki/Monomorphization) happens, but is not known during type checking. This includes - [checked generic parameters](#checked-and-template-parameters). + [checked-generic parameters](#checked-and-template-parameters), and type + expressions with checked-generic arguments, like `Optional(T*)`. - A _runtime value_ has a dynamic value only known at runtime. Carbon will automatically convert a constant to a symbolic value, or any value From ab4ec71c24a3d611bd0235851e7b9ef9b0c1fb89 Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 11 Jul 2022 21:53:19 +0000 Subject: [PATCH 13/22] Checkpoint progress. --- docs/design/README.md | 60 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index d819d3a75d00d..6d932c8a6be9c 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -391,14 +391,13 @@ are available for representing strings with `\`s and `"`s. ## Value categories and value phases -FIXME: -[wikipedia]() -[cppreference](https://en.cppreference.com/w/cpp/language/value_category) - **FIXME:** Should this be moved together with [Types are values](#types-are-values)? -Values are either _l-values_ or _r-values_. Carbon will automatically convert an +Every value has a +[value category](), +similar to [C++](https://en.cppreference.com/w/cpp/language/value_category), +that is either _l-value_ or _r-value_. Carbon will automatically convert an l-value to an r-value, but not in the other direction. L-values have storage and a stable address. They may be modified, assuming their @@ -514,9 +513,6 @@ There are no [null pointers](https://en.wikipedia.org/wiki/Null_pointer) in Carbon. To represent a pointer that may not refer to a valid object, use the type `Optional(T*)`. -Pointers are the main Carbon mechanism for allowing a function to modify a -variable of the caller. - **TODO:** Perhaps Carbon will have [stricter pointer provenance](https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html) or restrictions on casts between pointers and integers. @@ -693,11 +689,14 @@ it a _`var` binding_. [l-value](#value-categories-and-value-phases) which can be modified and has a stable address. -FIXME: have to be a const-reference or copy; which one must not be observable to -the programmer - -FIXME: aspects of the type can determine whether to copy, for example a type -that is not copyable will always use a const-reference +A `let`-binding may trigger a copy of the original value, or a move if the +original value a temporary, or the binding may be a pointer to the original +value, like a +[`const` reference in C++](). +Which option must not be observable to the programmer. For example, Carbon will +not allow modifications to the original value when it is through a pointer. This +choice may also be influenced by the type. For example, types that don't support +being copied will be passed by pointer instead. A [generic binding](#checked-and-template-parameters) uses `:!` instead of a colon (`:`) and can only match compile-time values, either a @@ -855,17 +854,8 @@ fn Add(a: i64, b: i64) -> i64 { ``` The names of the parameters are in scope until the end of the definition or -declaration. - -The bindings in the parameter list default to -[`let` bindings](#binding-patterns), and so the parameter names are treated as -[r-values](#value-categories-and-value-phases). If the `var` keyword is added -before the binding, then the arguments will be copied to new storage, and so can -be mutated in the function body. The copy ensures that any mutations will not be -visible to the caller. - -The parameter names in a forward declaration may be omitted using `_`, but must -match the definition if they are specified. +declaration. The parameter names in a forward declaration may be omitted using +`_`, but must match the definition if they are specified. > References: > @@ -881,14 +871,24 @@ match the definition if they are specified. ### Parameters -FIXME - The bindings in the parameter list default to [`let` bindings](#binding-patterns), and so the parameter names are treated as -[r-values](#value-categories-and-value-phases). If the `var` keyword is added -before the binding, then the arguments will be copied to new storage, and so can -be mutated in the function body. The copy ensures that any mutations will not be -visible to the caller. +[r-values](#value-categories-and-value-phases). This is appropriate for input +parameters. This binding will be implemented using a const reference, unless it +is legal to copy and copying is cheaper. + +If the `var` keyword is added before the binding, then the arguments will be +copied to new storage, and so can be mutated in the function body. The copy +ensures that any mutations will not be visible to the caller. + +Use a [pointer](#pointer-types) parameter type to represent an +[input/output parameter](), +allowing a function to modify a variable of the caller's. This makes the +possibility of those modifications visible: by taking the address using `&` in +the caller, and dereferencing using `*` in the callee. + +Outputs of a function should prefer to be returned. Multiple values may be +returned using a [tuple](#tuples) or [struct](#struct-types) type. ### `auto` return type From b2ad961f958629ee9952b41ee77129d8fc4b0edb Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 11 Jul 2022 22:02:31 +0000 Subject: [PATCH 14/22] Other operations --- docs/design/README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 6d932c8a6be9c..04f4585ee8177 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -2699,6 +2699,7 @@ The interfaces that correspond to each operator are given by: - **TODO:** [Assignment](#assignment-statements): `x = y`, `++x`, `x += y`, and so on - **TODO:** Dereference: `*p` +- **TODO:** [Move](#move): `~x` - **TODO:** Indexing: `a[3]` - **TODO:** Function call: `f(4)` @@ -2713,8 +2714,9 @@ Operators that can take multiple arguments, such as function calling operator `f(4)`, have a [variadic](generics/details.md#variadic-arguments) parameter list. -FIXME: Other operations on types not associated with operators like copy, move, -unformed, swap, etc. +Whether and how a value supports other operations, such as being copied, +swapped, or set into an [unformed state](#unformed-state), is also determined by +implementing corresponding interfaces for the value's type. > References: > From 8b57a8341ca1e16cbfaaeea6525acf9295f91959 Mon Sep 17 00:00:00 2001 From: Josh L Date: Mon, 11 Jul 2022 22:10:39 +0000 Subject: [PATCH 15/22] More about unformed --- docs/design/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index 04f4585ee8177..de6cba1f6c8d7 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1643,7 +1643,9 @@ An unformed state for an object is one that satisfies the following properties: A type might have more than one in-memory representation for the unformed state, and those representations may be the same as valid fully formed values for that type. For example, all values are legal representations of the unformed state -for any type with a trivial destructor like `i32`. +for any type with a trivial destructor like `i32`. Types may define additional +initialization for [hardened build mode](#build-modes). For example, this causes +integers to be set to `0` when in unformed state in this mode. Any operation on an unformed object _other_ than destruction or assignment to a fully formed value is an error, even if its in-memory representation is that of From ed93c5f7d290062455975a7e65eceb18120e1830 Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 13 Jul 2022 20:24:49 +0000 Subject: [PATCH 16/22] Operations interact with value phases, value phases for generic parameters --- docs/design/README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/design/README.md b/docs/design/README.md index de6cba1f6c8d7..181d1705c1504 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -431,6 +431,10 @@ graph TD; D(l-value)-->C; ``` +Symbolic values will generally convert into runtime values if an operation is +performed on them. Operations on just constant values will generally result in +constants. + ## Composite types ### Tuples @@ -2269,6 +2273,9 @@ templates. Constraints can then be added incrementally, with the compiler verifying that the semantics stay the same. Once all constraints have been added, removing the word `template` to switch to a checked parameter is safe. +The [value phase](#value-categories-and-value-phases) of a checked parameter is +a symbolic value whereas the value phase of a template parameter is constant. + Although checked generics are generally preferred, templates enable translation of code between C++ and Carbon, and address some cases where the type checking rigor of generics are problematic. From d91f0ab3dc1335755b3f8a17a7fe3e7517da32cf Mon Sep 17 00:00:00 2001 From: josh11b Date: Wed, 13 Jul 2022 14:57:30 -0700 Subject: [PATCH 17/22] Apply suggestions from code review Co-authored-by: Geoff Romer --- docs/design/README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 181d1705c1504..94881e531659b 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -407,7 +407,7 @@ R-values may not have dedicated storage. This means they can not be modified and their address generally cannot be taken. R-values are broken down into three kinds, called _value phases_: -- A _constant_ has value known at compile time, and that value is available +- A _constant_ has a value known at compile time, and that value is available during type checking, for example to use as the size of an array. These include literals ([integer](#integer-literals), [floating-point](#floating-point-literals), [string](#string-literals)), @@ -694,7 +694,7 @@ it a _`var` binding_. a stable address. A `let`-binding may trigger a copy of the original value, or a move if the -original value a temporary, or the binding may be a pointer to the original +original value is a temporary, or the binding may be a pointer to the original value, like a [`const` reference in C++](). Which option must not be observable to the programmer. For example, Carbon will @@ -703,8 +703,9 @@ choice may also be influenced by the type. For example, types that don't support being copied will be passed by pointer instead. A [generic binding](#checked-and-template-parameters) uses `:!` instead of a -colon (`:`) and can only match compile-time values, either a -[constant or symbolic value](#value-categories-and-value-phases). +colon (`:`) and can only match +[constant or symbolic values](#value-categories-and-value-phases), +not run-time values. The keyword `auto` may be used in place of the type in a binding pattern, as long as the type can be deduced from the type of a value in the same @@ -878,7 +879,7 @@ declaration. The parameter names in a forward declaration may be omitted using The bindings in the parameter list default to [`let` bindings](#binding-patterns), and so the parameter names are treated as [r-values](#value-categories-and-value-phases). This is appropriate for input -parameters. This binding will be implemented using a const reference, unless it +parameters. This binding will be implemented using a pointer, unless it is legal to copy and copying is cheaper. If the `var` keyword is added before the binding, then the arguments will be @@ -1631,7 +1632,7 @@ p->x += 2; #### Unformed state Types indicate that they support unformed states by -[implementing an interface](#interfaces-and-implementations), otherwise +[implementing a particular interface](#interfaces-and-implementations), otherwise variables of that type must be explicitly initialized when they are declared. An unformed state for an object is one that satisfies the following properties: @@ -1648,10 +1649,10 @@ A type might have more than one in-memory representation for the unformed state, and those representations may be the same as valid fully formed values for that type. For example, all values are legal representations of the unformed state for any type with a trivial destructor like `i32`. Types may define additional -initialization for [hardened build mode](#build-modes). For example, this causes +initialization for the [hardened build mode](#build-modes). For example, this causes integers to be set to `0` when in unformed state in this mode. -Any operation on an unformed object _other_ than destruction or assignment to a +Any operation on an unformed object _other_ than destruction or assignment from a fully formed value is an error, even if its in-memory representation is that of a valid value for that type. From 45da2054768f0c3439043a0a2ce348dd22dd95ca Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 13 Jul 2022 21:58:05 +0000 Subject: [PATCH 18/22] Fix formatting --- docs/design/README.md | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 94881e531659b..26f6c55b07683 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -704,8 +704,8 @@ being copied will be passed by pointer instead. A [generic binding](#checked-and-template-parameters) uses `:!` instead of a colon (`:`) and can only match -[constant or symbolic values](#value-categories-and-value-phases), -not run-time values. +[constant or symbolic values](#value-categories-and-value-phases), not run-time +values. The keyword `auto` may be used in place of the type in a binding pattern, as long as the type can be deduced from the type of a value in the same @@ -879,8 +879,8 @@ declaration. The parameter names in a forward declaration may be omitted using The bindings in the parameter list default to [`let` bindings](#binding-patterns), and so the parameter names are treated as [r-values](#value-categories-and-value-phases). This is appropriate for input -parameters. This binding will be implemented using a pointer, unless it -is legal to copy and copying is cheaper. +parameters. This binding will be implemented using a pointer, unless it is legal +to copy and copying is cheaper. If the `var` keyword is added before the binding, then the arguments will be copied to new storage, and so can be mutated in the function body. The copy @@ -1632,8 +1632,9 @@ p->x += 2; #### Unformed state Types indicate that they support unformed states by -[implementing a particular interface](#interfaces-and-implementations), otherwise -variables of that type must be explicitly initialized when they are declared. +[implementing a particular interface](#interfaces-and-implementations), +otherwise variables of that type must be explicitly initialized when they are +declared. An unformed state for an object is one that satisfies the following properties: @@ -1649,12 +1650,12 @@ A type might have more than one in-memory representation for the unformed state, and those representations may be the same as valid fully formed values for that type. For example, all values are legal representations of the unformed state for any type with a trivial destructor like `i32`. Types may define additional -initialization for the [hardened build mode](#build-modes). For example, this causes -integers to be set to `0` when in unformed state in this mode. +initialization for the [hardened build mode](#build-modes). For example, this +causes integers to be set to `0` when in unformed state in this mode. -Any operation on an unformed object _other_ than destruction or assignment from a -fully formed value is an error, even if its in-memory representation is that of -a valid value for that type. +Any operation on an unformed object _other_ than destruction or assignment from +a fully formed value is an error, even if its in-memory representation is that +of a valid value for that type. > References: > From 18e0c2d9d692bbe45c058131b641f1d4d0f6bfb8 Mon Sep 17 00:00:00 2001 From: Josh L Date: Wed, 13 Jul 2022 22:00:16 +0000 Subject: [PATCH 19/22] Provisional --- docs/design/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/design/README.md b/docs/design/README.md index 26f6c55b07683..1ed2948054d19 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -1591,6 +1591,9 @@ type, use `UnsafeDelete`. #### `const` +**Note:** This is provisional, no design for `const` has been through the +proposal process yet. + For every type `MyClass`, there is the type `const MyClass` such that: - The data representation is the same, so a `MyClass*` value may be implicitly From 198c7bd152bc4e223f1fc2484455e17ba31f19f9 Mon Sep 17 00:00:00 2001 From: Josh L Date: Thu, 14 Jul 2022 17:44:58 +0000 Subject: [PATCH 20/22] Fix missing ; --- docs/design/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/README.md b/docs/design/README.md index 1ed2948054d19..346a3c578b504 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -2875,7 +2875,7 @@ A C++ library header file may be [imported](#imports) into Carbon using an ```carbon // like `#include "circle.h"` in C++ -import Cpp library "circle.h" +import Cpp library "circle.h"; ``` This adds the names from `circle.h` into the `Cpp` namespace. If `circle.h` From a65bb1f054fceb5766621cacf8349963ea698d00 Mon Sep 17 00:00:00 2001 From: josh11b Date: Thu, 14 Jul 2022 21:41:54 -0700 Subject: [PATCH 21/22] Apply suggestions from code review Co-authored-by: Richard Smith Co-authored-by: Chandler Carruth --- docs/design/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index 346a3c578b504..c662ec9d71f97 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -403,7 +403,7 @@ l-value to an r-value, but not in the other direction. L-values have storage and a stable address. They may be modified, assuming their type is not [`const`](#const). -R-values may not have dedicated storage. This means they can not be modified and +R-values may not have dedicated storage. This means they cannot be modified and their address generally cannot be taken. R-values are broken down into three kinds, called _value phases_: @@ -431,9 +431,10 @@ graph TD; D(l-value)-->C; ``` -Symbolic values will generally convert into runtime values if an operation is -performed on them. Operations on just constant values will generally result in -constants. +Constants convert to symbolic values and to runtime values. Symbolic values +will generally convert into runtime values if an operation that inspects the +value is performed on them. Runtime values will convert into constants or to +symbolic values if constant evaluation of the runtime expression succeeds. ## Composite types @@ -687,7 +688,7 @@ Binding patterns default to _`let` bindings_. The `var` keyword is used to make it a _`var` binding_. - The result of a `let` binding is the name is bound to an - [r-value](#value-categories-and-value-phases). This means the value can not + [r-value](#value-categories-and-value-phases). This means the value cannot be modified, and its address generally cannot be taken. - A `var` binding has dedicated storage, and so the name is an [l-value](#value-categories-and-value-phases) which can be modified and has @@ -883,7 +884,7 @@ parameters. This binding will be implemented using a pointer, unless it is legal to copy and copying is cheaper. If the `var` keyword is added before the binding, then the arguments will be -copied to new storage, and so can be mutated in the function body. The copy +copied (or moved from a temporary) to new storage, and so can be mutated in the function body. The copy ensures that any mutations will not be visible to the caller. Use a [pointer](#pointer-types) parameter type to represent an From d99b58e34974417f1f0062da2ddf30631e72a3f6 Mon Sep 17 00:00:00 2001 From: Josh L Date: Fri, 15 Jul 2022 04:46:50 +0000 Subject: [PATCH 22/22] Fix formatting --- docs/design/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/design/README.md b/docs/design/README.md index c662ec9d71f97..eb86b4c1cf58a 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -431,10 +431,10 @@ graph TD; D(l-value)-->C; ``` -Constants convert to symbolic values and to runtime values. Symbolic values -will generally convert into runtime values if an operation that inspects the -value is performed on them. Runtime values will convert into constants or to -symbolic values if constant evaluation of the runtime expression succeeds. +Constants convert to symbolic values and to runtime values. Symbolic values will +generally convert into runtime values if an operation that inspects the value is +performed on them. Runtime values will convert into constants or to symbolic +values if constant evaluation of the runtime expression succeeds. ## Composite types @@ -884,8 +884,9 @@ parameters. This binding will be implemented using a pointer, unless it is legal to copy and copying is cheaper. If the `var` keyword is added before the binding, then the arguments will be -copied (or moved from a temporary) to new storage, and so can be mutated in the function body. The copy -ensures that any mutations will not be visible to the caller. +copied (or moved from a temporary) to new storage, and so can be mutated in the +function body. The copy ensures that any mutations will not be visible to the +caller. Use a [pointer](#pointer-types) parameter type to represent an [input/output parameter](),