Răsfoiți Sursa

Update design docs with syntax changes from #2760 (#2866)

This includes:

- Syntax changes from this chart:

| Before                          | After                                   |
| ------------------------------- | --------------------------------------- |
| `class D extends B { ... }`     | `class D { extend base: B; ... }`       |
| `external impl C as Sub;`       | `impl C as Sub;`                        |
| `class C { impl as Sortable; }` | `class C { extend impl as Sortable; }`  |
| `adapter A for C { ... }`       | `class A { adapt C; ... }`              |
| `adapter A extends C { ... }`   | `class A { extend adapt C; ... }`       |
| `interface I { impl as J; }`    | `interface I { require Self impls J; }` |
| `interface I { extends J; }`    | `interface I { extend J; }`             |

- Dropping the syntax for conditionally implemented internal interfaces.

This does not include:

- terminology changes from #2760 ("internal" and "external")
- changes to code, such as explorer, toolchain, language grammars, or other tooling
josh11b 2 ani în urmă
părinte
comite
2ae8117d62

+ 26 - 17
docs/design/README.md

@@ -1724,9 +1724,16 @@ Classes may only extend a single class. Carbon only supports single inheritance,
 and will use mixins instead of multiple inheritance.
 
 ```carbon
-base class MiddleDerived extends MyBaseClass { ... }
-class FinalDerived extends MiddleDerived { ... }
-// ❌ Forbidden: class Illegal extends FinalDerived { ... }
+base class MiddleDerived {
+  extend base: MyBaseClass;
+  ...
+}
+class FinalDerived {
+  extend base: MiddleDerived;
+  ...
+}
+// ❌ Forbidden: class Illegal { extend base: FinalDerived; ... }
+// may not extend `FinalDerived` since not declared `base` or `abstract`.
 ```
 
 A base class may define
@@ -1761,7 +1768,8 @@ For purposes of construction, a derived class acts like its first field is
 called `base` with the type of its immediate base class.
 
 ```carbon
-class MyDerivedType extends MyBaseType {
+class MyDerivedType {
+  extend base: MyBaseType;
   fn Make() -> MyDerivedType {
     return {.base = MyBaseType.Make(), .derived_field = 7};
   }
@@ -1785,7 +1793,8 @@ abstract class AbstractClass {
 // ❌ Error: can't instantiate abstract class
 var abc: AbstractClass = ...;
 
-class DerivedFromAbstract extends AbstractClass {
+class DerivedFromAbstract {
+  extend base: AbstractClass;
   fn Make() -> Self {
     // AbstractClass.Make() returns a
     // `partial AbstractClass` that can be used as
@@ -2398,8 +2407,8 @@ or [named constraint](generics/details.md#named-constraints), possibly renamed:
 
 ```carbon
 class ContactInfo {
-  external impl as Printable;
-  external impl as ToPrinterDevice;
+  impl as Printable;
+  impl as ToPrinterDevice;
   alias PrintToScreen = Printable.Print;
   alias PrintToPrinter = ToPrinterDevice.Print;
   ...
@@ -2667,7 +2676,7 @@ sufficient.
 class Circle {
   var radius: f32;
 
-  impl as Printable {
+  extend impl as Printable {
     fn Print[self: Self]() {
       Carbon.Print("Circle with radius: {0}", self.radius);
     }
@@ -2773,14 +2782,14 @@ values for the `ElementType` member of the interface using a `where` clause:
 
 ```carbon
 class IntStack {
-  impl as StackInterface where .ElementType = i32 {
+  extend impl as StackInterface where .ElementType = i32 {
     fn Push[addr self: Self*](value: i32);
     // ...
   }
 }
 
 class FruitStack {
-  impl as StackInterface where .ElementType = Fruit {
+  extend impl as StackInterface where .ElementType = Fruit {
     fn Push[addr self: Self*](value: Fruit);
     // ...
   }
@@ -2886,12 +2895,12 @@ An `impl` declaration may be parameterized by adding `forall [`_generic
 parameter list_`]` after the `impl` keyword introducer, as in:
 
 ```carbon
-external impl forall [T:! Printable] Vector(T) as Printable;
-external impl forall [Key:! Hashable, Value:! type]
+impl forall [T:! Printable] Vector(T) as Printable;
+impl forall [Key:! Hashable, Value:! type]
     HashMap(Key, Value) as Has(Key);
-external impl forall [T:! Ordered] T as PartiallyOrdered;
-external impl forall [T:! ImplicitAs(i32)] BigInt as AddWith(T);
-external impl forall [U:! type, T:! As(U)]
+impl forall [T:! Ordered] T as PartiallyOrdered;
+impl forall [T:! ImplicitAs(i32)] BigInt as AddWith(T);
+impl forall [U:! type, T:! As(U)]
     Optional(T) as As(Optional(U));
 ```
 
@@ -3014,7 +3023,7 @@ to type `T` and the second argument to type `U`, add the `like` keyword to both
 types in the `impl` declaration, as in:
 
 ```carbon
-external impl like T as AddWith(like U) where .Result = V {
+impl like T as AddWith(like U) where .Result = V {
   // `Self` is `T` here
   fn Op[self: Self](other: U) -> V { ... }
 }
@@ -3024,7 +3033,7 @@ When the operand types and result type are all the same, this is equivalent to
 implementing the `Add` interface:
 
 ```carbon
-external impl T as Add {
+impl T as Add {
   fn Op[self: Self](other: Self) -> Self { ... }
 }
 ```

+ 11 - 11
docs/design/assignment.md

@@ -177,7 +177,7 @@ provided for built-in types as necessary to give the semantics described above.
 interface AssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint Assign { extends AssignWith(Self); }
+constraint Assign { extend AssignWith(Self); }
 ```
 
 Given `var x: T` and `y: U`:
@@ -191,7 +191,7 @@ Given `var x: T` and `y: U`:
 interface AddAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint AddAssign { extends AddAssignWith(Self); }
+constraint AddAssign { extend AddAssignWith(Self); }
 ```
 
 ```
@@ -199,7 +199,7 @@ constraint AddAssign { extends AddAssignWith(Self); }
 interface SubAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint SubAssign { extends SubAssignWith(Self); }
+constraint SubAssign { extend SubAssignWith(Self); }
 ```
 
 ```
@@ -207,7 +207,7 @@ constraint SubAssign { extends SubAssignWith(Self); }
 interface MulAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint MulAssign { extends MulAssignWith(Self); }
+constraint MulAssign { extend MulAssignWith(Self); }
 ```
 
 ```
@@ -215,7 +215,7 @@ constraint MulAssign { extends MulAssignWith(Self); }
 interface DivAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint DivAssign { extends DivAssignWith(Self); }
+constraint DivAssign { extend DivAssignWith(Self); }
 ```
 
 ```
@@ -223,7 +223,7 @@ constraint DivAssign { extends DivAssignWith(Self); }
 interface ModAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint ModAssign { extends ModAssignWith(Self); }
+constraint ModAssign { extend ModAssignWith(Self); }
 ```
 
 ```
@@ -250,7 +250,7 @@ Given `var x: T` and `y: U`:
 interface BitAndAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint BitAndAssign { extends BitAndAssignWith(Self); }
+constraint BitAndAssign { extend BitAndAssignWith(Self); }
 ```
 
 ```
@@ -258,7 +258,7 @@ constraint BitAndAssign { extends BitAndAssignWith(Self); }
 interface BitOrAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint BitOrAssign { extends BitOrAssignWith(Self); }
+constraint BitOrAssign { extend BitOrAssignWith(Self); }
 ```
 
 ```
@@ -266,7 +266,7 @@ constraint BitOrAssign { extends BitOrAssignWith(Self); }
 interface BitXorAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint BitXorAssign { extends BitXorAssignWith(Self); }
+constraint BitXorAssign { extend BitXorAssignWith(Self); }
 ```
 
 ```
@@ -274,7 +274,7 @@ constraint BitXorAssign { extends BitXorAssignWith(Self); }
 interface LeftShiftAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint LeftShiftAssign { extends LeftShiftAssignWith(Self); }
+constraint LeftShiftAssign { extend LeftShiftAssignWith(Self); }
 ```
 
 ```
@@ -282,7 +282,7 @@ constraint LeftShiftAssign { extends LeftShiftAssignWith(Self); }
 interface RightShiftAssignWith(U:! type) {
   fn Op[addr self: Self*](other: U);
 }
-constraint RightShiftAssign { extends RightShiftAssignWith(Self); }
+constraint RightShiftAssign { extend RightShiftAssignWith(Self); }
 ```
 
 Given `var x: T` and `y: U`:

+ 45 - 21
docs/design/classes.md

@@ -684,7 +684,6 @@ The declarations for nominal class types will have:
 -   an optional `abstract` or `base` prefix
 -   `class` introducer
 -   the name of the class
--   an optional `extends` followed by the name of the immediate base class
 -   `{`, an open curly brace
 -   a sequence of declarations
 -   `}`, a close curly brace
@@ -712,9 +711,9 @@ determined at compile time.
 To support circular references between class types, we allow
 [forward declaration](https://en.wikipedia.org/wiki/Forward_declaration) of
 types. Forward declarations end with semicolon `;` after the name of the class,
-instead of any `extends` clause and the block of declarations in curly braces
-`{`...`}`. A type that is forward declared is considered incomplete until the
-end of a definition with the same name.
+instead of the block of declarations in curly braces `{`...`}`. A type that is
+forward declared is considered incomplete until the end of a definition with the
+same name.
 
 ```
 // Forward declaration of `GraphNode`.
@@ -1132,9 +1131,16 @@ base class MyBaseClass { ... }
 A _base class_ may be _extended_ to get a _derived class_:
 
 ```
-base class MiddleDerived extends MyBaseClass { ... }
-class FinalDerived extends MiddleDerived { ... }
-// ❌ Forbidden: class Illegal extends FinalDerived { ... }
+base class MiddleDerived {
+  extend base: MyBaseClass;
+  ...
+}
+class FinalDerived {
+  extend base: MiddleDerived;
+  ...
+}
+// ❌ Forbidden: class Illegal { extend base: FinalDerived; ... }
+// may not extend `FinalDerived` since not declared `base` or `abstract`.
 ```
 
 An _[abstract class](https://en.wikipedia.org/wiki/Abstract_type)_ or _abstract
@@ -1218,7 +1224,7 @@ There are three virtual override keywords:
     doesn't match the base class. We intentionally use the same keyword here as
     for implementing interfaces, to emphasize that they are similar operations.
 
-| Keyword on<br />method in `C` | Allowed in<br />`abstract class C` | Allowed in<br />`base class C` | Allowed in<br />final `class C` | in `B` where<br />`C extends B`                          | in `D` where<br />`D extends C`                                                  |
+| Keyword on<br />method in `C` | Allowed in<br />`abstract class C` | Allowed in<br />`base class C` | Allowed in<br />final `class C` | in `B` where<br />`C` extends `B`                        | in `D` where<br />`D` extends `C`                                                |
 | ----------------------------- | ---------------------------------- | ------------------------------ | ------------------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------- |
 | `virtual`                     | ✅                                 | ✅                             | ❌                              | _not present_                                            | `abstract`<br />`impl`<br />_not mentioned_                                      |
 | `abstract`                    | ✅                                 | ❌                             | ❌                              | _not present_<br />`virtual`<br />`abstract`<br />`impl` | `abstract`<br />`impl`<br />_may not be<br />mentioned if<br />`D` is not final_ |
@@ -1252,7 +1258,10 @@ base class Extensible { ... }
 // Can be replaced by:
 
 abstract class ExtensibleBase { ... }
-class ExactlyExtensible extends ExtensibleBase { ... }
+class ExactlyExtensible {
+  extend base: ExtensibleBase;
+  ...
+}
 ```
 
 #### `Self` refers to the current type
@@ -1269,7 +1278,8 @@ base class B1 {
   //   virtual fn F[self: B1](x: B1) -> B1;
 }
 
-class D1 extends B1 {
+class D1 {
+  extend base: B1;
   // ❌ Illegal:
   //   impl fn F[self: Self](x: Self) -> Self;
   // since that would mean the same thing as:
@@ -1294,7 +1304,8 @@ base class B2 {
   //   virtual fn Clone[self: B2]() -> B2*;
 }
 
-class D2 extends B2 {
+class D2 {
+  extend base: B2;
   // ✅ Allowed
   impl fn Clone[self: Self]() -> Self*;
   // Means the same thing as:
@@ -1320,7 +1331,8 @@ type, this time with a `.base` member to initialize the members of the immediate
 base type.
 
 ```
-class MyDerivedType extends MyBaseType {
+class MyDerivedType {
+  extend base: MyBaseType;
   fn Create() -> MyDerivedType {
     return {.base = MyBaseType.Create(), .derived_field = ...};
   }
@@ -1455,7 +1467,8 @@ abstract class MyAbstractClass {
 }
 
 // Base class returns a partial type
-base class Derived extends MyAbstractClass {
+base class Derived {
+  extend base: MyAbstractClass;
   protected fn Create() -> partial Self {
     return {.base = MyAbstractClass.Create(), .derived_field = ...};
   }
@@ -1467,7 +1480,8 @@ base class MyBaseClass {
 }
 
 // Base class returns a full type
-base class ExtensibleDerived extends MyBaseClass {
+base class ExtensibleDerived {
+  extend base: MyBaseClass;
   fn Create() -> Self {
     return {.base = MyBaseClass.Create(), .derived_field = ...};
   }
@@ -1478,7 +1492,8 @@ base class ExtensibleDerived extends MyBaseClass {
 And final classes will return a type that does not use the partial facet:
 
 ```
-class FinalDerived extends MiddleDerived {
+class FinalDerived {
+  extend base: MiddleDerived;
   fn Create() -> Self {
     return {.base = MiddleDerived.Create(), .derived_field = ...};
   }
@@ -1572,7 +1587,8 @@ base class MyBaseClass {
   virtual destructor [addr self: Self*] { ... }
 }
 
-class MyDerivedClass extends MyBaseClass {
+class MyDerivedClass {
+  extend base: MyBaseClass;
   impl destructor [addr self: Self*] { ... }
 }
 ```
@@ -1633,7 +1649,8 @@ function expecting a `Deletable` type, use the `UnsafeAllowDelete`
 [type adapter](/docs/design/generics/details.md#adapting-types).
 
 ```
-adapter UnsafeAllowDelete(T:! Concrete) extends T {
+class UnsafeAllowDelete(T:! Concrete) {
+  extend adapt T;
   impl as Deletable {}
 }
 
@@ -1777,7 +1794,8 @@ base class MyBaseClass {
   protected var data: i32;
 }
 
-class MyDerivedClass extends MyBaseClass {
+class MyDerivedClass {
+  extend base: MyBaseClass;
   fn UsesProtected[addr self: Self*]() {
     // Can access protected members in derived class
     var x: i32 = HelperClassFunction(3);
@@ -1975,9 +1993,10 @@ There are some opportunities to improve on and simplify the C++ story:
 This design directly supports Carbon classes inheriting from a single C++ class.
 
 ```
-class CarbonClass extends C++.CPlusPlusClass {
+class CarbonClass {
+  extend base: Cpp.CPlusPlusClass;
   fn Create() -> Self {
-    return {.base = C++.CPlusPlusClass(...), .other_fields = ...};
+    return {.base = Cpp.CPlusPlusClass(...), .other_fields = ...};
   }
   ...
 }
@@ -2132,7 +2151,7 @@ interface ConstructWidgetFrom {
   fn Construct(Self) -> Widget;
 }
 
-external impl {.kind: WidgetKind, .size: i32}
+impl {.kind: WidgetKind, .size: i32}
     as ConstructWidgetFrom { ... }
 ```
 
@@ -2233,6 +2252,10 @@ the type of `U.x`."
 
     -   [No unqualified lookup when defining outside a scope](/proposals/p2287.md#no-unqualified-lookup-when-defining-outside-a-scope)
 
+-   [#2760: Consistent `class` and `interface` syntax](https://github.com/carbon-language/carbon-lang/pull/2760)
+    -   [Use `extends` instead of `extend`](/proposals/p2760.md#use-extends-instead-of-extend)
+    -   [List base class in class declaration](/proposals/p2760.md#list-base-class-in-class-declaration)
+
 ## References
 
 -   [#257: Initialization of memory and variables](https://github.com/carbon-language/carbon-lang/pull/257)
@@ -2244,3 +2267,4 @@ the type of `U.x`."
 -   [#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154)
 -   [#2107: Clarify rules around `Self` and `.Self`](https://github.com/carbon-language/carbon-lang/pull/2107)
 -   [#2287: Allow unqualified name lookup for class members](https://github.com/carbon-language/carbon-lang/pull/2287)
+-   [#2760: Consistent `class` and `interface` syntax](https://github.com/carbon-language/carbon-lang/pull/2760)

+ 1 - 1
docs/design/expressions/README.md

@@ -235,7 +235,7 @@ with parentheses around the member name:
 ```
 interface I { fn F[self: Self](); }
 class X {}
-external impl X as I { fn F[self: Self]() {} }
+impl X as I { fn F[self: Self]() {} }
 
 // `x.I.F()` would mean `(x.I).F()`.
 fn Q(x: X) { x.(I.F)(); }

+ 5 - 5
docs/design/expressions/arithmetic.md

@@ -205,7 +205,7 @@ interface AddWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint Add {
-  extends AddWith(Self) where .Result = Self;
+  extend AddWith(Self) where .Result = Self;
 }
 ```
 
@@ -216,7 +216,7 @@ interface SubWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint Sub {
-  extends SubWith(Self) where .Result = Self;
+  extend SubWith(Self) where .Result = Self;
 }
 ```
 
@@ -227,7 +227,7 @@ interface MulWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint Mul {
-  extends MulWith(Self) where .Result = Self;
+  extend MulWith(Self) where .Result = Self;
 }
 ```
 
@@ -238,7 +238,7 @@ interface DivWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint Div {
-  extends DivWith(Self) where .Result = Self;
+  extend DivWith(Self) where .Result = Self;
 }
 ```
 
@@ -249,7 +249,7 @@ interface ModWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint Mod {
-  extends ModWith(Self) where .Result = Self;
+  extend ModWith(Self) where .Result = Self;
 }
 ```
 

+ 5 - 5
docs/design/expressions/bitwise.md

@@ -209,7 +209,7 @@ interface BitAndWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint BitAnd {
-  extends BitAndWith(Self) where .Result = Self;
+  extend BitAndWith(Self) where .Result = Self;
 }
 ```
 
@@ -220,7 +220,7 @@ interface BitOrWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint BitOr {
-  extends BitOrWith(Self) where .Result = Self;
+  extend BitOrWith(Self) where .Result = Self;
 }
 ```
 
@@ -231,7 +231,7 @@ interface BitXorWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint BitXor {
-  extends BitXorWith(Self) where .Result = Self;
+  extend BitXorWith(Self) where .Result = Self;
 }
 ```
 
@@ -242,7 +242,7 @@ interface LeftShiftWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint LeftShift {
-  extends LeftShiftWith(Self) where .Result = Self;
+  extend LeftShiftWith(Self) where .Result = Self;
 }
 ```
 
@@ -253,7 +253,7 @@ interface RightShiftWith(U:! type) {
   fn Op[self: Self](other: U) -> Result;
 }
 constraint RightShift {
-  extends RightShiftWith(Self) where .Result = Self;
+  extend RightShiftWith(Self) where .Result = Self;
 }
 ```
 

+ 12 - 12
docs/design/expressions/comparison_operators.md

@@ -260,7 +260,7 @@ interface EqWith(U:! type) {
   }
 }
 constraint Eq {
-  extends EqWith(Self);
+  extend EqWith(Self);
 }
 ```
 
@@ -275,7 +275,7 @@ class Path {
   private var path: String;
   private fn CanonicalPath[self: Self]() -> String;
 
-  external impl as Eq {
+  impl as Eq {
     fn Equal[self: Self](other: Self) -> bool {
       return (self.drive, self.CanonicalPath()) ==
              (other.drive, other.CanonicalPath());
@@ -295,8 +295,8 @@ class MyInt {
   var value: i32;
   fn Value[self: Self]() -> i32 { return self.value; }
 }
-external impl i32 as ImplicitAs(MyInt);
-external impl like MyInt as EqWith(like MyInt) {
+impl i32 as ImplicitAs(MyInt);
+impl like MyInt as EqWith(like MyInt) {
   fn Equal[self: Self](other: Self) -> bool {
     return self.Value() == other.Value();
   }
@@ -315,7 +315,7 @@ and `NotEqual` to return `true` for the same pair of values. Additionally, these
 operations should have no observable side-effects.
 
 ```
-external impl like MyFloat as EqWith(like MyFloat) {
+impl like MyFloat as EqWith(like MyFloat) {
   fn Equal[self: MyFloat](other: MyFloat) -> bool {
     if (self.IsNaN() or other.IsNaN()) {
       return false;
@@ -334,8 +334,8 @@ external impl like MyFloat as EqWith(like MyFloat) {
 Heterogeneous comparisons must be defined both ways around:
 
 ```
-external impl like MyInt as EqWith(like MyFloat);
-external impl like MyFloat as EqWith(like MyInt);
+impl like MyInt as EqWith(like MyFloat);
+impl like MyFloat as EqWith(like MyInt);
 ```
 
 **TODO:** Add an adapter to the standard library to make it easy to define the
@@ -371,12 +371,12 @@ interface OrderedWith(U:! type) {
   }
 }
 constraint Ordered {
-  extends OrderedWith(Self);
+  extend OrderedWith(Self);
 }
 
 // Ordering.Less < Ordering.Equivalent < Ordering.Greater.
 // Ordering.Incomparable is incomparable with all three.
-external impl Ordering as Ordered;
+impl Ordering as Ordered;
 ```
 
 **TODO:** Revise the above when we have a concrete design for enumerated types.
@@ -398,7 +398,7 @@ class MyWidget {
   fn Size[self: Self]() -> i32 { return self.width * self.height; }
 
   // Widgets are normally ordered by size.
-  external impl as Ordered {
+  impl as Ordered {
     fn Compare[self: Self](other: Self) -> Ordering {
       return self.Size().(Ordered.Compare)(other.Size());
     }
@@ -418,8 +418,8 @@ heterogeneous comparisons must be defined both ways around:
 fn ReverseOrdering(o: Ordering) -> Ordering {
   return Ordering.Equivalent.(Ordered.Compare)(o);
 }
-external impl like MyInt as OrderedWith(like MyFloat);
-external impl like MyFloat as OrderedWith(like MyInt) {
+impl like MyInt as OrderedWith(like MyFloat);
+impl like MyFloat as OrderedWith(like MyInt) {
   fn Compare[self: Self](other: Self) -> Ordering {
     return Reverse(other.(OrderedWith(Self).Compare)(self));
   }

+ 3 - 3
docs/design/expressions/implicit_conversions.md

@@ -172,8 +172,8 @@ to `Base**` because that would allow storing a `Derived2*` into a `Derived*`:
 
 ```
 abstract class Base {}
-class Derived extends Base {}
-class Derived2 extends Base {}
+class Derived { extend base: Base; }
+class Derived2 { extend base: Base; }
 var d2: Derived2 = {};
 var p: Derived*;
 var q: Derived2* = &d2;
@@ -208,7 +208,7 @@ extends
 
 ```
 interface ImplicitAs(Dest:! type) {
-  extends As(Dest);
+  extend As(Dest);
   // Inherited from As(Dest):
   // fn Convert[self: Self]() -> Dest;
 }

+ 4 - 4
docs/design/expressions/indexing.md

@@ -55,7 +55,7 @@ interface IndexWith(SubscriptType:! type) {
 }
 
 interface IndirectIndexWith(SubscriptType:! type) {
-  impl as IndexWith(SubscriptType);
+  require Self impls IndexWith(SubscriptType);
   fn Addr[self: Self](subscript: SubscriptType) -> ElementType*;
 }
 ```
@@ -74,7 +74,7 @@ implement `IndirectIndexWith(I)`:
 `IndirectIndexWith` provides a blanket `final impl` for `IndexWith`:
 
 ```
-final external impl forall
+final impl forall
     [SubscriptType:! type, T:! IndirectIndexWith(SubscriptType)]
     T as IndexWith(SubscriptType) {
   let ElementType:! type = T.(IndirectIndexWith(SubscriptType)).ElementType;
@@ -96,7 +96,7 @@ An array type could implement subscripting like so:
 
 ```
 class Array(template T:! type) {
-  external impl as IndexWith(like i64) {
+  impl as IndexWith(like i64) {
     let ElementType:! type = T;
     fn At[self: Self](subscript: i64) -> T;
     fn Addr[addr self: Self*](subscript: i64) -> T*;
@@ -108,7 +108,7 @@ And a type such as `std::span` could look like this:
 
 ```
 class Span(T:! type) {
-  external impl as IndirectIndexWith(like i64) {
+  impl as IndirectIndexWith(like i64) {
     let ElementType:! type = T;
     fn Addr[self: Self](subscript: i64) -> T*;
   }

+ 15 - 14
docs/design/expressions/member_access.md

@@ -60,7 +60,7 @@ interface Widget {
 class Cog {
   var size: i32;
   fn Make(size: i32) -> Self;
-  impl as Widgets.Widget;
+  extend impl as Widgets.Widget;
 }
 
 fn GrowSomeCogs() {
@@ -165,12 +165,12 @@ For example:
 interface Printable {
   fn Print[self: Self]();
 }
-external impl i32 as Printable;
+impl i32 as Printable;
 class Point {
   var x: i32;
   var y: i32;
   // Internal impl injects the name `Print` into class `Point`.
-  impl as Printable;
+  extend impl as Printable;
 }
 
 fn PrintPointTwice() {
@@ -242,7 +242,7 @@ class Cowboy { fn Draw[self: Self](); }
 interface Renderable {
   fn Draw[self: Self]();
 }
-external impl Cowboy as Renderable { fn Draw[self: Self](); }
+impl Cowboy as Renderable { fn Draw[self: Self](); }
 fn DrawDirect(c: Cowboy) { c.Draw(); }
 fn DrawGeneric[T:! Renderable](c: T) { c.Draw(); }
 fn DrawTemplate[template T:! Renderable](c: T) { c.Draw(); }
@@ -257,7 +257,7 @@ fn Draw(c: Cowboy) {
 }
 
 class RoundWidget {
-  external impl as Renderable {
+  impl as Renderable {
     fn Draw[self: Self]();
   }
   alias Draw = Renderable.Draw;
@@ -265,7 +265,7 @@ class RoundWidget {
 
 class SquareWidget {
   fn Draw[self: Self]() {}
-  external impl as Renderable {
+  impl as Renderable {
     alias Draw = Self.Draw;
   }
 }
@@ -311,7 +311,7 @@ interface Addable {
 }
 
 class Integer {
-  impl as Addable {
+  extend impl as Addable {
     // #3
     fn Add[self: Self](other: Self) -> Self;
     // #4, generated from default implementation for #2.
@@ -372,7 +372,7 @@ interface I {
   let N:! i32;
 }
 class C {
-  impl as I where .N = 5 {
+  extend impl as I where .N = 5 {
     // #2
     fn F[self: C]() {}
   }
@@ -417,7 +417,7 @@ interface Renderable {
 }
 
 class RoundWidget {
-  external impl as Renderable {
+  impl as Renderable {
     // #2
     fn Draw[self: Self]();
   }
@@ -428,7 +428,7 @@ class RoundWidget {
 class SquareWidget {
   // #3
   fn Draw[self: Self]() {}
-  external impl as Renderable {
+  impl as Renderable {
     alias Draw = Self.Draw;
   }
 }
@@ -480,8 +480,9 @@ base class WidgetBase {
   }
 }
 
-class TriangleWidget extends WidgetBase {
-  external impl as Renderable;
+class TriangleWidget {
+  extend base: WidgetBase;
+  impl as Renderable;
 }
 fn DrawTriangle(t: TriangleWidget) {
   // ✅ OK: name `Draw` resolves to `Draw` member of `WidgetBase`, which
@@ -582,7 +583,7 @@ always used for lookup.
 interface Printable {
   fn Print[self: Self]();
 }
-external impl i32 as Printable {
+impl i32 as Printable {
   fn Print[self: Self]();
 }
 fn MemberAccess(n: i32) {
@@ -621,7 +622,7 @@ class A {
 interface B {
   fn F();
 }
-external impl A as B;
+impl A as B;
 
 fn Use(a: A) {
   // Calls member `F` of class `A.B`.

Fișier diff suprimat deoarece este prea mare
+ 193 - 171
docs/design/generics/details.md


+ 24 - 22
docs/design/generics/overview.md

@@ -205,27 +205,27 @@ class Song {
   // ...
 
   // Implementing `Printable` for `Song` inside the definition of `Song`
-  // without the keyword `external` means all names of `Printable`, such
+  // with the keyword `extend` means all names of `Printable`, such
   // as `F`, are included as a part of the `Song` API.
-  impl as Printable {
+  extend impl as Printable {
     // Could use `Self` in place of `Song` here.
     fn Print[self: Song]() { ... }
   }
 }
 
 // Implement `Comparable` for `Song` without changing the API of `Song`
-// using an `external impl` declaration. This may be defined in either
-// the library defining `Song` or `Comparable`.
-external impl Song as Comparable {
+// using an `impl` declaration without `extend`. This may be defined in
+// either the library defining `Song` or `Comparable`.
+impl Song as Comparable {
   // Could use either `Self` or `Song` here.
   fn Less[self: Self](rhs: Self) -> bool { ... }
 }
 ```
 
 Implementations may be defined within the class definition itself or
-out-of-line. Implementations may optionally start with the `external` keyword to
-say the members of the interface are not members of the class. Out-of-line
-implementations must be external. External implementations may be defined in the
+out-of-line. Implementations may optionally start with the `extend` keyword to
+say the members of the interface are also members of the class, which may only
+be used in a class scope. Otherwise, implementations may be defined in the
 library defining either the class or the interface.
 
 #### Accessing members of interfaces
@@ -355,12 +355,12 @@ interface Equatable {
 
 // `Iterable` requires that `Equatable` is implemented.
 interface Iterable {
-  impl as Equatable;
+  require Self impls Equatable;
   fn Advance[addr self: Self*]();
 }
 ```
 
-The `extends` keyword is used to [extend](terminology.md#extending-an-interface)
+The `extend` keyword is used to [extend](terminology.md#extending-an-interface)
 another interface. If interface `Derived` extends interface `Base`, `Base`'s
 interface is both required and all its methods are included in `Derived`'s
 interface.
@@ -368,12 +368,12 @@ interface.
 ```
 // `Hashable` extends `Equatable`.
 interface Hashable {
-  extends Equatable;
+  extend Equatable;
   fn Hash[self: Self]() -> u64;
 }
 // `Hashable` is equivalent to:
 interface Hashable {
-  impl as Equatable;
+  require Self impls Equatable;
   alias IsEqual = Equatable.IsEqual;
   fn Hash[self: Self]() -> u64;
 }
@@ -385,7 +385,7 @@ methods in the implementation of the derived interface.
 ```
 class Key {
   // ...
-  impl as Hashable {
+  extend impl as Hashable {
     fn IsEqual[self: Key](rhs: Key) -> bool { ... }
     fn Hash[self: Key]() -> u64 { ... }
   }
@@ -439,8 +439,8 @@ applications and capabilities not covered here.
 
 ```
 constraint Combined {
-  impl as Renderable;
-  impl as EndOfGame;
+  require Self impls Renderable;
+  require Self impls EndOfGame;
   alias Draw_Renderable = Renderable.Draw;
   alias Draw_EndOfGame = EndOfGame.Draw;
   alias SetWinner = EndOfGame.SetWinner;
@@ -472,7 +472,7 @@ For example: If there were a class `CDCover` defined this way:
 
 ```
 class CDCover  {
-  impl as Printable {
+  extend impl as Printable {
     ...
   }
 }
@@ -503,12 +503,14 @@ In this example, we have multiple ways of sorting a collection of `Song` values.
 ```
 class Song { ... }
 
-adapter SongByArtist extends Song {
-  impl as Comparable { ... }
+class SongByArtist {
+  extend adapt Song;
+  extend impl as Comparable { ... }
 }
 
-adapter SongByTitle extends Song {
-  impl as Comparable { ... }
+class SongByTitle {
+  extend adapt Song;
+  extend impl as Comparable { ... }
 }
 ```
 
@@ -610,7 +612,7 @@ of associated types (and other associated constants).
 
 ```
 class Vector(T:! Movable) {
-  impl as Stack where .ElementType = T { ... }
+  extend impl as Stack where .ElementType = T { ... }
 }
 ```
 
@@ -649,7 +651,7 @@ supports any type implicitly convertible to a specified type, using `like`:
 // Support multiplying values of type `Distance` with
 // values of type `f64` or any type implicitly
 // convertible to `f64`.
-external impl Distance as MultipliableWith(like f64) ...
+impl Distance as MultipliableWith(like f64) ...
 ```
 
 ## Future work

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

@@ -347,9 +347,9 @@ instead of associated entity.
 
 ## Impl: Implementation of an interface
 
-An _impl_ is an implementation of an interface for a specific type. It is the
-place where the function bodies are defined, values for associated types, etc.
-are given. Implementations are needed for
+An _impl_ is an implementation of an interface for a specific type, called the
+_implementing type_. It is the place where the function bodies are defined,
+values for associated types, etc. are given. Implementations are needed for
 [nominal interfaces](#nominal-interfaces);
 [structural interfaces](#structural-interfaces) and
 [named constraints](#named-constraints) define conformance implicitly instead of
@@ -678,7 +678,7 @@ class Fruit;
 class FruitStack {
   // Implement `Stack` for `FruitStack`
   // with `ElementType` set to `Fruit`.
-  impl as Stack where .ElementType == Fruit { ... }
+  extend impl as Stack where .ElementType == Fruit { ... }
 }
 ```
 

+ 6 - 6
docs/design/sum_types.md

@@ -83,9 +83,9 @@ match (my_opt) {
 have limited flexibility. There is no way to control the representation of a
 `choice` type, or define methods or other members for it (although you can
 extend it to implement interfaces, using an
-[`external impl`](generics/overview.md#implementing-interfaces) or
-[`adapter`](generics/overview.md#adapting-types)). However, a `class` type can
-be extended to behave like a sum type. This is much more verbose than a `choice`
+[external `impl`](generics/overview.md#implementing-interfaces) or
+[adapter](generics/overview.md#adapting-types)). However, a `class` type can be
+extended to behave like a sum type. This is much more verbose than a `choice`
 declaration, but gives the author full control over the representation and class
 members.
 
@@ -143,9 +143,9 @@ class Optional(T:! type) {
   private var has_value: bool;
   private var value: T;
 
-  external impl as Match {
+  impl as Match {
     interface Continuation {
-      extends Match.BaseContinuation;
+      extend Match.BaseContinuation;
       fn Some[addr self: Self*](value: T) -> ReturnType;
       fn None[addr self: Self*]() -> ReturnType;
     }
@@ -170,7 +170,7 @@ look, if it were written in Carbon:
 
 ```carbon
 class __MatchStatementImpl {
-  impl as Match(Optional.MatchContinuation) where .ReturnType = () {
+  extend impl as Match(Optional.MatchContinuation) where .ReturnType = () {
     fn Some(the_value: i32) {
       Print(the_value);
     }

Unele fișiere nu au fost afișate deoarece prea multe fișiere au fost modificate în acest diff