Parcourir la source

Replace `addr` with `ref` in design docs (#6141)

Updates the documentation under `docs/design/` to use `ref` instead of
`addr` after their removal in #5434. Care was taken to manually clean up
edge cases and, in a couple cases, surrounding text (see
3d72c49bb75c0f40ca7e8114b6a1369b941e1697). After this change, there are
no matches for `addr(?!ess)` in `docs/design/`.

Closes #6032
Calvin il y a 6 mois
Parent
commit
bd4d5805dd

+ 17 - 18
docs/design/README.md

@@ -1767,16 +1767,16 @@ class Point {
     return Math.Sqrt(dx * dx + dy * dy);
   }
   // Mutating method declaration
-  fn Offset[addr self: Self*](dx: i32, dy: i32);
+  fn Offset[ref self: Self](dx: i32, dy: i32);
 
   var x: i32;
   var y: i32;
 }
 
 // Out-of-line definition of method declared inline
-fn Point.Offset[addr self: Self*](dx: i32, dy: i32) {
-  self->x += dx;
-  self->y += dy;
+fn Point.Offset[ref self: Self](dx: i32, dy: i32) {
+  self.x += dx;
+  self.y += dy;
 }
 
 var origin: Point = {.x = 0, .y = 0};
@@ -1796,10 +1796,9 @@ two methods `Distance` and `Offset`:
 -   `Distance` computes and returns the distance to another point, without
     modifying the `Point`. This is signified using `[self: Self]` in the method
     declaration.
--   `origin.Offset(`...`)` does modify the value of `origin`. This is signified
-    using `[addr self: Self*]` in the method declaration. Since calling this
-    method requires taking the [non-`const`](#const) address of `origin`, it may
-    only be called on [reference expressions](#expression-categories).
+-   `origin.Offset(`...`)` _does_ modify the value of `origin`. This is
+    signified using `[ref self: Self]` in the method declaration. It may only be
+    called on [reference expressions](#expression-categories).
 -   Methods may be declared lexically inline like `Distance`, or lexically out
     of line like `Offset`.
 
@@ -1955,7 +1954,7 @@ names resolvable by the compiler, and don't act like forward declarations.
 
 A destructor for a class is custom code executed when the lifetime of a value of
 that type ends. They are defined with `fn destroy` followed by either
-`[self: Self]` or `[addr self: Self*]` (as is done with [methods](#methods)) and
+`[self: Self]` or `[ref self: Self]` (as is done with [methods](#methods)) and
 the block of code in the class definition, as in:
 
 ```carbon
@@ -1969,7 +1968,7 @@ or:
 ```carbon
 class MyClass {
   // Can modify `self` in the body.
-  fn destroy[addr self: Self*]() { ... }
+  fn destroy[ref self: Self]() { ... }
 }
 ```
 
@@ -2004,8 +2003,8 @@ For every type `MyClass`, there is the type `const MyClass` such that:
     has type `const T`.
 -   While all of the member names in `MyClass` are also member names in
     `const MyClass`, the effective API of a `const MyClass` reference expression
-    is a subset of `MyClass`, because only `addr` methods accepting a
-    `const Self*` will be valid.
+    is a subset of `MyClass`, because only `ref` methods accepting a
+    `const Self` will be valid.
 
 Note that `const` binds more tightly than postfix-`*` for forming a pointer
 type, so `const MyClass*` is equal to `(const MyClass)*`.
@@ -2996,8 +2995,8 @@ associated constant to represent the type of elements stored in the stack.
 ```
 interface StackInterface {
   let ElementType:! Movable;
-  fn Push[addr self: Self*](value: ElementType);
-  fn Pop[addr self: Self*]() -> ElementType;
+  fn Push[ref self: Self](value: ElementType);
+  fn Pop[ref self: Self]() -> ElementType;
   fn IsEmpty[self: Self]() -> bool;
 }
 ```
@@ -3008,14 +3007,14 @@ for the `ElementType` member of the interface using a `where` clause:
 ```carbon
 class IntStack {
   extend impl as StackInterface where .ElementType = i32 {
-    fn Push[addr self: Self*](value: i32);
+    fn Push[ref self: Self](value: i32);
     // ...
   }
 }
 
 class FruitStack {
   extend impl as StackInterface where .ElementType = Fruit {
-    fn Push[addr self: Self*](value: Fruit);
+    fn Push[ref self: Self](value: Fruit);
     // ...
   }
 }
@@ -3043,8 +3042,8 @@ values of any type `T`:
 
 ```carbon
 class Stack(T:! type) {
-  fn Push[addr self: Self*](value: T);
-  fn Pop[addr self: Self*]() -> T;
+  fn Push[ref self: Self](value: T);
+  fn Pop[ref self: Self]() -> T;
 
   var storage: Array(T);
 }

+ 16 - 17
docs/design/assignment.md

@@ -73,9 +73,8 @@ standard library.
 ## Syntax
 
 The operands of these operators can be any [expression](expressions/README.md).
-However, the first operand must be modifiable because it is passed to an
-`[addr self: Self*]` parameter, which disallows most expression forms other
-than:
+However, the first operand must be modifiable because it is passed to a
+`[ref self: Self]` parameter, which disallows most expression forms other than:
 
 -   The name of a `var` binding.
 -   A dereference of a pointer.
@@ -175,7 +174,7 @@ provided for built-in types as necessary to give the semantics described above.
 ```
 // Simple `=`.
 interface AssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint Assign { extend AssignWith(Self); }
 ```
@@ -189,7 +188,7 @@ Given `var x: T` and `y: U`:
 ```
 // Compound `+=`.
 interface AddAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint AddAssign { extend AddAssignWith(Self); }
 ```
@@ -197,7 +196,7 @@ constraint AddAssign { extend AddAssignWith(Self); }
 ```
 // Compound `-=`.
 interface SubAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint SubAssign { extend SubAssignWith(Self); }
 ```
@@ -205,7 +204,7 @@ constraint SubAssign { extend SubAssignWith(Self); }
 ```
 // Compound `*=`.
 interface MulAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint MulAssign { extend MulAssignWith(Self); }
 ```
@@ -213,7 +212,7 @@ constraint MulAssign { extend MulAssignWith(Self); }
 ```
 // Compound `/=`.
 interface DivAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint DivAssign { extend DivAssignWith(Self); }
 ```
@@ -221,16 +220,16 @@ constraint DivAssign { extend DivAssignWith(Self); }
 ```
 // Compound `%=`.
 interface ModAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint ModAssign { extend ModAssignWith(Self); }
 ```
 
 ```
 // Increment `++`.
-interface Inc { fn Op[addr self: Self*](); }
+interface Inc { fn Op[ref self: Self](); }
 // Decrement `++`.
-interface Dec { fn Op[addr self: Self*](); }
+interface Dec { fn Op[ref self: Self](); }
 ```
 
 Given `var x: T` and `y: U`:
@@ -248,7 +247,7 @@ Given `var x: T` and `y: U`:
 ```
 // Compound `&=`.
 interface BitAndAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint BitAndAssign { extend BitAndAssignWith(Self); }
 ```
@@ -256,7 +255,7 @@ constraint BitAndAssign { extend BitAndAssignWith(Self); }
 ```
 // Compound `|=`.
 interface BitOrAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint BitOrAssign { extend BitOrAssignWith(Self); }
 ```
@@ -264,7 +263,7 @@ constraint BitOrAssign { extend BitOrAssignWith(Self); }
 ```
 // Compound `^=`.
 interface BitXorAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint BitXorAssign { extend BitXorAssignWith(Self); }
 ```
@@ -272,7 +271,7 @@ constraint BitXorAssign { extend BitXorAssignWith(Self); }
 ```
 // Compound `<<=`.
 interface LeftShiftAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint LeftShiftAssign { extend LeftShiftAssignWith(Self); }
 ```
@@ -280,7 +279,7 @@ constraint LeftShiftAssign { extend LeftShiftAssignWith(Self); }
 ```
 // Compound `>>=`.
 interface RightShiftAssignWith(U:! type) {
-  fn Op[addr self: Self*](other: U);
+  fn Op[ref self: Self](other: U);
 }
 constraint RightShiftAssign { extend RightShiftAssignWith(Self); }
 ```
@@ -310,7 +309,7 @@ This defaulting is accomplished by a parameterized implementation of
 ```
 impl forall [U:! type, T:! OpWith(U) where .Self impls AssignWith(.Self.Result)]
     T as OpAssignWith(U) {
-  fn Op[addr self: Self*](other: U) {
+  fn Op[ref self: Self](other: U) {
     // Here, `$` is the operator described by `OpWith`.
     *self = *self $ other;
   }

+ 16 - 17
docs/design/classes.md

@@ -903,14 +903,14 @@ class Circle {
   fn Diameter[self: Self]() -> f32 {
     return self.radius * 2;
   }
-  fn Expand[addr self: Self*](distance: f32);
+  fn Expand[ref self: Self](distance: f32);
 
   var center: Point;
   var radius: f32;
 }
 
-fn Circle.Expand[addr self: Self*](distance: f32) {
-  self->radius += distance;
+fn Circle.Expand[ref self: Self](distance: f32) {
+  self.radius += distance;
 }
 
 var c: Circle = {.center = Point.Origin(), .radius = 1.5 };
@@ -925,12 +925,11 @@ Assert(Math.Abs(c.Diameter() - 4.0) < 0.001);
     the `Circle` instance. This is signified using `[self: Self]` in the method
     declaration.
 -   `c.Expand(`...`)` does modify the value of `c`. This is signified using
-    `[addr self: Self*]` in the method declaration.
+    `[ref self: Self]` in the method declaration.
 
-The pattern '`addr self:` _type_' means "first take the address of the argument,
-which must be an
-[l-value](<https://en.wikipedia.org/wiki/Value_(computer_science)#lrvalue>), and
-then match pattern '`self:` _type_' against it".
+The pattern '`ref self:` _type_' means "the argument must be a
+[reference expression](/docs/design/values.md#reference-expressions), and must
+match the pattern '`self:` _type_'".
 
 If the method declaration also includes
 [deduced compile-time parameters](/docs/design/generics/overview.md#deduced-parameters),
@@ -1585,7 +1584,7 @@ or:
 ```carbon
 class MyClass {
   // Can modify `self` in the body.
-  fn destroy[addr self: Self*]() { ... }
+  fn destroy[ref self: Self]() { ... }
 }
 ```
 
@@ -1608,9 +1607,9 @@ Destructors may be declared in class scope and then defined out-of-line:
 
 ```carbon
 class MyClass {
-  fn destroy[addr self: Self*]();
+  fn destroy[ref self: Self]();
 }
-fn MyClass.destroy[addr self: Self*]() { ... }
+fn MyClass.destroy[ref self: Self]() { ... }
 ```
 
 It is illegal to delete an instance of a derived class through a pointer to one
@@ -1622,12 +1621,12 @@ must be `override`:
 
 ```carbon
 base class MyBaseClass {
-  virtual fn destroy[addr self: Self*]() { ... }
+  virtual fn destroy[ref self: Self]() { ... }
 }
 
 class MyDerivedClass {
   extend base: MyBaseClass;
-  override fn destroy[addr self: Self*]() { ... }
+  override fn destroy[ref self: Self]() { ... }
 }
 ```
 
@@ -1677,8 +1676,8 @@ call the `UnsafeDelete` method instead. Note that you may not call
 ```
 interface Allocator {
   // ...
-  fn Delete[T:! Deletable, addr self: Self*](p: T*);
-  fn UnsafeDelete[T:! Destructible, addr self: Self*](p: T*);
+  fn Delete[T:! Deletable, ref self: Self](p: T*);
+  fn UnsafeDelete[T:! Destructible, ref self: Self](p: T*);
 }
 ```
 
@@ -1835,10 +1834,10 @@ base class MyBaseClass {
 
 class MyDerivedClass {
   extend base: MyBaseClass;
-  fn UsesProtected[addr self: Self*]() {
+  fn UsesProtected[ref self: Self]() {
     // Can access protected members in derived class
     var x: i32 = HelperClassFunction(3);
-    self->data = self->HelperMethod(x);
+    self.data = self.HelperMethod(x);
   }
 }
 ```

+ 4 - 8
docs/design/expressions/member_access.md

@@ -76,7 +76,7 @@ For example:
 namespace Widgets;
 
 interface Widgets.Widget {
-  fn Grow[addr self: Self*](factor: f64);
+  fn Grow[ref self: Self](factor: f64);
 }
 
 class Widgets.Cog {
@@ -765,19 +765,15 @@ If instance binding is performed:
 
 -   For a method, the result is a _bound method_, which is a value `F` such that
     a function call `F(args)` behaves the same as a call to `M(args)` with the
-    `self` parameter initialized by a corresponding recipient argument:
-
-    -   If the method declares its `self` parameter with `addr`, the recipient
-        argument is `&x`.
-    -   Otherwise, the recipient argument is `x`.
+    `self` parameter initialized by `x`.
 
     ```carbon
     class Blob {
-      fn Mutate[addr self: Self*](n: i32);
+      fn Mutate[ref self: Self](n: i32);
     }
     fn F(p: Blob*) {
       // ✅ OK, forms bound method `((*p).M)` and calls it.
-      // This calls `Blob.Mutate` with `self` initialized by `&(*p)`
+      // This calls `Blob.Mutate` with `self` initialized by `*p`
       // and `n` initialized by `5`.
       (*p).Mutate(5);
 

+ 2 - 2
docs/design/generics/appendix-witness.md

@@ -241,12 +241,12 @@ witness table.
 
 ```
 interface Iterator {
-  fn Advance[addr self: Self*]();
+  fn Advance[ref self: Self]();
 }
 
 interface Container {
   let IteratorType:! Iterator;
-  fn Begin[addr self: Self*]() -> IteratorType;
+  fn Begin[ref self: Self]() -> IteratorType;
 }
 ```
 

+ 56 - 56
docs/design/generics/details.md

@@ -1210,7 +1210,7 @@ we use the same semantics and `require Self impls` syntax as we do for
 interface Equatable { fn Equals[self: Self](rhs: Self) -> bool; }
 
 interface Iterable {
-  fn Advance[addr self: Self*]() -> bool;
+  fn Advance[ref self: Self]() -> bool;
   require Self impls Equatable;
 }
 
@@ -1431,7 +1431,7 @@ Conversely, an `interface` can extend a `constraint`:
 interface MovieCodec {
   extend Combined;
 
-  fn Load[addr self: Self*](filename: String);
+  fn Load[ref self: Self](filename: String);
 }
 ```
 
@@ -1445,7 +1445,7 @@ interface MovieCodec {
   require Self impls Job;
   alias Run = Job.Run;
 
-  fn Load[addr self: Self*](filename: String);
+  fn Load[ref self: Self](filename: String);
 }
 ```
 
@@ -1459,19 +1459,19 @@ Consider this set of interfaces, simplified from
 
 ```carbon
 interface Graph {
-  fn Source[addr self: Self*](e: EdgeDescriptor) -> VertexDescriptor;
-  fn Target[addr self: Self*](e: EdgeDescriptor) -> VertexDescriptor;
+  fn Source[ref self: Self](e: EdgeDescriptor) -> VertexDescriptor;
+  fn Target[ref self: Self](e: EdgeDescriptor) -> VertexDescriptor;
 }
 
 interface IncidenceGraph {
   extend Graph;
-  fn OutEdges[addr self: Self*](u: VertexDescriptor)
+  fn OutEdges[ref self: Self](u: VertexDescriptor)
     -> (EdgeIterator, EdgeIterator);
 }
 
 interface EdgeListGraph {
   extend Graph;
-  fn Edges[addr self: Self*]() -> (EdgeIterator, EdgeIterator);
+  fn Edges[ref self: Self]() -> (EdgeIterator, EdgeIterator);
 }
 ```
 
@@ -1498,11 +1498,11 @@ though could be defined in the `impl` block of `IncidenceGraph`,
       extend impl as IncidenceGraph {
         fn Source[self: Self](e: EdgeDescriptor) -> VertexDescriptor { ... }
         fn Target[self: Self](e: EdgeDescriptor) -> VertexDescriptor { ... }
-        fn OutEdges[addr self: Self*](u: VertexDescriptor)
+        fn OutEdges[ref self: Self](u: VertexDescriptor)
             -> (EdgeIterator, EdgeIterator) { ... }
       }
       extend impl as EdgeListGraph {
-        fn Edges[addr self: Self*]() -> (EdgeIterator, EdgeIterator) { ... }
+        fn Edges[ref self: Self]() -> (EdgeIterator, EdgeIterator) { ... }
       }
     }
     ```
@@ -1514,12 +1514,12 @@ though could be defined in the `impl` block of `IncidenceGraph`,
     class MyEdgeListIncidenceGraph {
       extend impl as IncidenceGraph {
         fn Source[self: Self](e: EdgeDescriptor) -> VertexDescriptor { ... }
-        fn OutEdges[addr self: Self*](u: VertexDescriptor)
+        fn OutEdges[ref self: Self](u: VertexDescriptor)
             -> (EdgeIterator, EdgeIterator) { ... }
       }
       extend impl as EdgeListGraph {
         fn Target[self: Self](e: EdgeDescriptor) -> VertexDescriptor { ... }
-        fn Edges[addr self: Self*]() -> (EdgeIterator, EdgeIterator) { ... }
+        fn Edges[ref self: Self]() -> (EdgeIterator, EdgeIterator) { ... }
       }
     }
     ```
@@ -2021,10 +2021,10 @@ as an associated constant.
 interface NSpacePoint {
   let N:! i32;
   // The following require: 0 <= i < N.
-  fn Get[addr self: Self*](i: i32) -> f64;
-  fn Set[addr self: Self*](i: i32, value: f64);
+  fn Get[ref self: Self](i: i32) -> f64;
+  fn Set[ref self: Self](i: i32, value: f64);
   // Associated constants may be used in signatures:
-  fn SetAll[addr self: Self*](value: Array(f64, N));
+  fn SetAll[ref self: Self](value: Array(f64, N));
 }
 ```
 
@@ -2044,17 +2044,17 @@ a [`where` clause](#where-constraints). For example, implementations of
 ```carbon
 class Point2D {
   extend impl as NSpacePoint where .N = 2 {
-    fn Get[addr self: Self*](i: i32) -> f64 { ... }
-    fn Set[addr self: Self*](i: i32, value: f64) { ... }
-    fn SetAll[addr self: Self*](value: Array(f64, 2)) { ... }
+    fn Get[ref self: Self](i: i32) -> f64 { ... }
+    fn Set[ref self: Self](i: i32, value: f64) { ... }
+    fn SetAll[ref self: Self](value: Array(f64, 2)) { ... }
   }
 }
 
 class Point3D {
   extend impl as NSpacePoint where .N = 3 {
-    fn Get[addr self: Self*](i: i32) -> f64 { ... }
-    fn Set[addr self: Self*](i: i32, value: f64) { ... }
-    fn SetAll[addr self: Self*](value: Array(f64, 3)) { ... }
+    fn Get[ref self: Self](i: i32) -> f64 { ... }
+    fn Set[ref self: Self](i: i32, value: f64) { ... }
+    fn SetAll[ref self: Self](value: Array(f64, 3)) { ... }
   }
 }
 ```
@@ -2154,9 +2154,9 @@ a specified name. For example:
 ```carbon
 interface StackAssociatedFacet {
   let ElementType:! type;
-  fn Push[addr self: Self*](value: ElementType);
-  fn Pop[addr self: Self*]() -> ElementType;
-  fn IsEmpty[addr self: Self*]() -> bool;
+  fn Push[ref self: Self](value: ElementType);
+  fn Pop[ref self: Self]() -> ElementType;
+  fn IsEmpty[ref self: Self]() -> bool;
 }
 ```
 
@@ -2169,26 +2169,26 @@ of `StackAssociatedFacet` must also define. For example, maybe a `DynamicArray`
 ```carbon
 class DynamicArray(T:! type) {
   class IteratorType { ... }
-  fn Begin[addr self: Self*]() -> IteratorType;
-  fn End[addr self: Self*]() -> IteratorType;
-  fn Insert[addr self: Self*](pos: IteratorType, value: T);
-  fn Remove[addr self: Self*](pos: IteratorType);
+  fn Begin[ref self: Self]() -> IteratorType;
+  fn End[ref self: Self]() -> IteratorType;
+  fn Insert[ref self: Self](pos: IteratorType, value: T);
+  fn Remove[ref self: Self](pos: IteratorType);
 
   // Set the associated facet `ElementType` to `T`.
   extend impl as StackAssociatedFacet where .ElementType = T {
-    fn Push[addr self: Self*](value: ElementType) {
-      self->Insert(self->End(), value);
+    fn Push[ref self: Self](value: ElementType) {
+      self.Insert(self.End(), value);
     }
-    fn Pop[addr self: Self*]() -> ElementType {
-      var pos: IteratorType = self->End();
-      Assert(pos != self->Begin());
+    fn Pop[ref self: Self]() -> ElementType {
+      var pos: IteratorType = self.End();
+      Assert(pos != self.Begin());
       --pos;
       returned var ret: ElementType = *pos;
-      self->Remove(pos);
+      self.Remove(pos);
       return var;
     }
-    fn IsEmpty[addr self: Self*]() -> bool {
-      return self->Begin() == self->End();
+    fn IsEmpty[ref self: Self]() -> bool {
+      return self.Begin() == self.End();
     }
   }
 }
@@ -2290,9 +2290,9 @@ after the name of the interface:
 
 ```carbon
 interface StackParameterized(ElementType:! type) {
-  fn Push[addr self: Self*](value: ElementType);
-  fn Pop[addr self: Self*]() -> ElementType;
-  fn IsEmpty[addr self: Self*]() -> bool;
+  fn Push[ref self: Self](value: ElementType);
+  fn Pop[ref self: Self]() -> ElementType;
+  fn IsEmpty[ref self: Self]() -> bool;
 }
 ```
 
@@ -2304,25 +2304,25 @@ class Produce {
   var fruit: DynamicArray(Fruit);
   var veggie: DynamicArray(Veggie);
   extend impl as StackParameterized(Fruit) {
-    fn Push[addr self: Self*](value: Fruit) {
-      self->fruit.Push(value);
+    fn Push[ref self: Self](value: Fruit) {
+      self.fruit.Push(value);
     }
-    fn Pop[addr self: Self*]() -> Fruit {
-      return self->fruit.Pop();
+    fn Pop[ref self: Self]() -> Fruit {
+      return self.fruit.Pop();
     }
-    fn IsEmpty[addr self: Self*]() -> bool {
-      return self->fruit.IsEmpty();
+    fn IsEmpty[ref self: Self]() -> bool {
+      return self.fruit.IsEmpty();
     }
   }
   extend impl as StackParameterized(Veggie) {
-    fn Push[addr self: Self*](value: Veggie) {
-      self->veggie.Push(value);
+    fn Push[ref self: Self](value: Veggie) {
+      self.veggie.Push(value);
     }
-    fn Pop[addr self: Self*]() -> Veggie {
-      return self->veggie.Pop();
+    fn Pop[ref self: Self]() -> Veggie {
+      return self.veggie.Pop();
     }
-    fn IsEmpty[addr self: Self*]() -> bool {
-      return self->veggie.IsEmpty();
+    fn IsEmpty[ref self: Self]() -> bool {
+      return self.veggie.IsEmpty();
     }
   }
 }
@@ -2430,7 +2430,7 @@ parameters are required to always be different. For example:
 
 ```carbon
 interface Map(FromType:! type, ToType:! type) {
-  fn Map[addr self: Self*](needle: FromType) -> Optional(ToType);
+  fn Map[ref self: Self](needle: FromType) -> Optional(ToType);
 }
 class Bijection(FromType:! type, ToType:! type) {
   extend impl as Map(FromType, ToType) { ... }
@@ -2658,7 +2658,7 @@ interface Container {
   let SliceType:! Container where .Self impls SliceConstraint(ElementType, .Self);
 
   // `Self` means the type implementing `Container`.
-  fn GetSlice[addr self: Self*]
+  fn GetSlice[ref self: Self]
       (start: IteratorType, end: IteratorType) -> SliceType;
 }
 
@@ -2768,7 +2768,7 @@ with any mentioned parameters substituted into that type.
 interface Container {
   let Element:! type;
   let Slice:! Container where .Element = Element;
-  fn Add[addr self: Self*](x: Element);
+  fn Add[ref self: Self](x: Element);
 }
 // `T.Slice.Element` rewritten to `T.Element`
 //     because type of `T.Slice` says `.Element = Element`.
@@ -2960,7 +2960,7 @@ interface Edge {
 interface Node {
   let E:! EdgeFor(Self);
   fn GetE[self: Self]() -> E;
-  fn AddE[addr self: Self*](e: E);
+  fn AddE[ref self: Self](e: E);
   fn NearN[self: Self](n: Self) -> bool;
 }
 
@@ -6295,7 +6295,7 @@ class HashMap(
   // `Self` is `HashMap(KeyT, ValueT)`.
 
   // Class parameters may be used in function signatures.
-  fn Insert[addr self: Self*](k: KeyT, v: ValueT);
+  fn Insert[ref self: Self](k: KeyT, v: ValueT);
 
   // Class parameters may be used in field types.
   private var buckets: DynArray((KeyT, ValueT));
@@ -6371,7 +6371,7 @@ its elements implement the `Ordered` interface:
 ```carbon
 class DynArray(T:! type) {
   // `DynArray(T)` has a `Sort()` method if `T impls Ordered`.
-  fn Sort[C:! Ordered, addr self: DynArray(C)*]();
+  fn Sort[C:! Ordered, ref self: DynArray(C)]();
 }
 ```
 

+ 6 - 6
docs/design/generics/overview.md

@@ -390,7 +390,7 @@ interface Equatable {
 // `Iterable` requires that `Equatable` is implemented.
 interface Iterable {
   require Self impls Equatable;
-  fn Advance[addr self: Self*]();
+  fn Advance[ref self: Self]();
 }
 ```
 
@@ -442,9 +442,9 @@ interface Renderable {
   fn Draw[self: Self]();
 }
 interface EndOfGame {
-  fn SetWinner[addr self: Self*](player: i32);
+  fn SetWinner[ref self: Self](player: i32);
   // Indicate the game was a draw
-  fn Draw[addr self: Self*]();
+  fn Draw[ref self: Self]();
 }
 
 fn F[T:! Renderable & EndOfGame](game_state: T*) -> (i32, i32) {
@@ -568,9 +568,9 @@ convenient to use. Imagine a `Stack` interface. Different types implementing
 ```
 interface Stack {
   let ElementType:! Movable;
-  fn Push[addr self: Self*](value: ElementType);
-  fn Pop[addr self: Self*]() -> ElementType;
-  fn IsEmpty[addr self: Self*]() -> bool;
+  fn Push[ref self: Self](value: ElementType);
+  fn Pop[ref self: Self]() -> ElementType;
+  fn IsEmpty[ref self: Self]() -> bool;
 }
 ```
 

+ 2 - 2
docs/design/generics/terminology.md

@@ -752,8 +752,8 @@ associated constants.
 // Stack using associated facets
 interface Stack {
   let ElementType:! type;
-  fn Push[addr self: Self*](value: ElementType);
-  fn Pop[addr self: Self*]() -> ElementType;
+  fn Push[ref self: Self](value: ElementType);
+  fn Pop[ref self: Self]() -> ElementType;
 }
 
 // Works on any type implementing `Stack`. Return type

+ 1 - 1
docs/design/lambdas.md

@@ -474,7 +474,7 @@ let lambda: auto = fn [self] { self.F(); };
 
 Note: Following
 [#3720](https://github.com/carbon-language/carbon-lang/pull/3720), an expression
-of the form `x.(F)`, where `F` is a function with a `self` or `addr self`
+of the form `x.(F)`, where `F` is a function with a `self` or `ref self`
 parameter, produces a callable that holds the value of `x`, and does not hold
 the value of `F`. As a consequence, we can't support combining captures and
 function fields with a `self` parameter.

+ 1 - 1
docs/design/lexical_conventions/words.md

@@ -47,7 +47,6 @@ The following words are interpreted as keywords:
 
 -   `abstract`
 -   `adapt`
--   `addr`
 -   `alias`
 -   `and`
 -   `as`
@@ -89,6 +88,7 @@ The following words are interpreted as keywords:
 -   `partial`
 -   `private`
 -   `protected`
+-   `ref`
 -   `require`
 -   `return`
 -   `returned`

+ 2 - 2
docs/design/sum_types.md

@@ -146,8 +146,8 @@ class Optional(T:! type) {
   impl as Match {
     interface Continuation {
       extend Match.BaseContinuation;
-      fn Some[addr self: Self*](value: T) -> ReturnType;
-      fn None[addr self: Self*]() -> ReturnType;
+      fn Some[ref self: Self](value: T) -> ReturnType;
+      fn None[ref self: Self]() -> ReturnType;
     }
 
     fn Op[self: Self, C:! Continuation](continuation: C*) -> C.ReturnType {

+ 2 - 2
docs/design/templates.md

@@ -47,8 +47,8 @@ bound early to the extent possible. For example:
 class Stack(template T:! type) {
   var storage: Array(T);
 
-  fn Push[addr self: Self*](value: T);
-  fn Pop[addr self: Self*]() -> T;
+  fn Push[ref self: Self](value: T);
+  fn Pop[ref self: Self]() -> T;
 }
 ```
 

+ 24 - 29
docs/design/values.md

@@ -263,11 +263,6 @@ makes this a use case that requires a special marking on the declaration.
 _Reference expressions_ refer to _objects_ with _storage_ where a value may be
 read or written and the object's address can be taken.
 
-Calling a [method](/docs/design/classes.md#methods) on a reference expression
-where the method's `self` parameter has an `addr` specifier can always
-implicitly take the address of the referred-to object. This address is passed as
-a [pointer](#pointers) to the `self` parameter for such methods.
-
 There are two sub-categories of reference expressions: _durable_ and
 _ephemeral_. These refine the _lifetime_ of the underlying storage and provide
 safety restrictions reflecting that lifetime.
@@ -312,15 +307,15 @@ expressions_. They still refer to an object with storage, but it may be storage
 that will not outlive the full expression. Because the storage is only
 temporary, we impose restrictions on where these reference expressions can be
 used: their address can only be taken implicitly as part of a method call whose
-`self` parameter is marked with the `addr` specifier.
+`self` parameter is marked with the `ref` specifier.
 
 **Future work:** The current design allows directly requiring an ephemeral
-reference for `addr`-methods because this replicates the flexibility in C++ --
+reference for `ref`-methods because this replicates the flexibility in C++ --
 very few C++ methods are L-value-ref-qualified which would have a similar effect
-to `addr`-methods requiring a durable reference expression. This is leveraged
+to `ref`-methods requiring a durable reference expression. This is leveraged
 frequently in C++ for builder APIs and other patterns. However, Carbon provides
 more tools in this space than C++ already, and so it may be worth evaluating
-whether we can switch `addr`-methods to the same restrictions as assignment and
+whether we can switch `ref`-methods to the same restrictions as assignment and
 `&`. Temporaries would never have their address escaped (in a safe way) in that
 world and there would be fewer different kinds of entities. But this is reserved
 for future work as we should be very careful about the expressivity hit being
@@ -473,7 +468,7 @@ to the operation in question. For example:
 ```carbon
 class S {
   fn ValueMemberFunction[self: Self]();
-  fn AddrMemberFunction[addr self: const Self*]();
+  fn RefMemberFunction[ref self: const Self]();
 }
 
 fn F(s_value: S) {
@@ -481,7 +476,7 @@ fn F(s_value: S) {
   s_value.ValueMemberFunction();
 
   // This requires an unsafe marker in the syntax.
-  s_value.unsafe AddrMemberFunction();
+  s_value.unsafe RefMemberFunction();
 }
 ```
 
@@ -794,7 +789,7 @@ _thread-safe_ interface subset of an otherwise _thread-compatible_ type.
 
 Note that `const T` is a type qualification and is generally orthogonal to
 expression categories or what form of pattern is used, including for object
-parameters. Notionally, it can occur both with `addr` and value object
+parameters. Notionally, it can occur both with `ref` and value object
 parameters. However, on value patterns, it is redundant as there is no
 meaningful distinction between a value expression of type `T` and type
 `const T`. For example, given a type and methods:
@@ -803,20 +798,20 @@ meaningful distinction between a value expression of type `T` and type
 class X {
   fn Method[self: Self]();
   fn ConstMethod[self: const Self]();
-  fn AddrMethod[addr self: Self*]();
-  fn AddrConstMethod[addr self: const Self*]();
+  fn RefMethod[ref self: Self]();
+  fn RefConstMethod[ref self: const Self]();
 }
 ```
 
 The methods can be called on different kinds of expressions according to the
 following table:
 
-|  Expression category: | `let x: X` <br/> (value) | `let x: const X` <br/> (const value) | `var x: X` <br/> (reference) | `var x: const X` <br/> (const reference) |
-| --------------------: | ------------------------ | ------------------------------------ | ---------------------------- | ---------------------------------------- |
-|         `x.Method();` | ✅                       | ✅                                   | ✅                           | ✅                                       |
-|    `x.ConstMethod();` | ✅                       | ✅                                   | ✅                           | ✅                                       |
-|     `x.AddrMethod();` | ❌                       | ❌                                   | ✅                           | ❌                                       |
-| `x.AddrConstMethod()` | ❌                       | ❌                                   | ✅                           | ✅                                       |
+| Expression category: | `let x: X` <br/> (value) | `let x: const X` <br/> (const value) | `var x: X` <br/> (reference) | `var x: const X` <br/> (const reference) |
+| -------------------: | ------------------------ | ------------------------------------ | ---------------------------- | ---------------------------------------- |
+|        `x.Method();` | ✅                       | ✅                                   | ✅                           | ✅                                       |
+|   `x.ConstMethod();` | ✅                       | ✅                                   | ✅                           | ✅                                       |
+|     `x.RefMethod();` | ❌                       | ❌                                   | ✅                           | ❌                                       |
+| `x.RefConstMethod()` | ❌                       | ❌                                   | ✅                           | ✅                                       |
 
 The `const T` type has the same representation as `T` with the same field names,
 but all of its field types are also `const`-qualified. Other than fields, all
@@ -859,11 +854,11 @@ and realistic Carbon code patterns that cannot be expressed with the tools in
 this proposal in order to motivate a minimal extension. Some candidates based on
 functionality already proposed here or for [classes](/docs/design/classes.md):
 
--   Allow overloading between `addr me` and `me` in methods. This is among the
-    most appealing as it _doesn't_ have the combinatorial explosion. But it is
-    also very limited as it only applies to the implicit object parameter.
+-   Allow overloading between `ref self` and `self` in methods. This is among
+    the most appealing as it _doesn't_ have the combinatorial explosion. But it
+    is also very limited as it only applies to the implicit object parameter.
 -   Allow overloading between `var` and non-`var` parameters.
--   Expand the `addr` technique from object parameters to all parameters, and
+-   Expand the `ref` technique from object parameters to all parameters, and
     allow overloading based on it.
 
 Perhaps more options will emerge as well. Again, the goal isn't to completely
@@ -927,7 +922,7 @@ will require that the type containing that specifier satisfies the constraint
 ```carbon
 interface ReferenceImplicitAs {
   let T:! type;
-  fn Convert[addr self: const Self*]() -> T;
+  fn Convert[ref self: const Self]() -> T;
 }
 ```
 
@@ -972,11 +967,11 @@ class String {
   private var capacity: i64;
 
   impl as ReferenceImplicitAs where .T = StringView {
-    fn Op[addr self: const Self*]() -> StringView {
+    fn Op[ref self: const Self]() -> StringView {
       // Because this is called on the String object prior to it becoming
       // a value, we can access an SSO buffer or other interior pointers
       // of `self`.
-      return StringView.Make(self->data_ptr, self->size);
+      return StringView.Make(self.data_ptr, self.size);
     }
   }
 
@@ -998,8 +993,8 @@ class String {
   // Note that even though the `Self` type is `const` qualified here, this
   // cannot be called on a `String` value! That would require us to convert to a
   // `StringView` that does not track the extra data member.
-  fn Capacity[addr self: const Self*]() -> i64 {
-    return self->capacity;
+  fn Capacity[ref self: const Self]() -> i64 {
+    return self.capacity;
   }
 }
 ```