|
|
@@ -0,0 +1,169 @@
|
|
|
+# Clarify rules around `Self` and `.Self`
|
|
|
+
|
|
|
+<!--
|
|
|
+Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
|
+Exceptions. See /LICENSE for license information.
|
|
|
+SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
+-->
|
|
|
+
|
|
|
+[Pull request](https://github.com/carbon-language/carbon-lang/pull/2107)
|
|
|
+
|
|
|
+<!-- toc -->
|
|
|
+
|
|
|
+## Table of contents
|
|
|
+
|
|
|
+- [Abstract](#abstract)
|
|
|
+- [Problem](#problem)
|
|
|
+- [Background](#background)
|
|
|
+- [Proposal](#proposal)
|
|
|
+- [Details](#details)
|
|
|
+- [Rationale](#rationale)
|
|
|
+- [Alternatives considered](#alternatives-considered)
|
|
|
+ - [`Self` not a keyword](#self-not-a-keyword)
|
|
|
+ - [Make `Self` a member of all types](#make-self-a-member-of-all-types)
|
|
|
+ - [`where` operator could be associative](#where-operator-could-be-associative)
|
|
|
+
|
|
|
+<!-- tocstop -->
|
|
|
+
|
|
|
+## Abstract
|
|
|
+
|
|
|
+A number of smaller changes grouped together in one proposal:
|
|
|
+
|
|
|
+- Make `Self` a keyword.
|
|
|
+- Clarify that `Self` refers to the current type in a base class and in impl
|
|
|
+ declarations.
|
|
|
+- Clarify when `.Self` is legal, and what type it has.
|
|
|
+- Also specify that `where` is not an associative operator.
|
|
|
+
|
|
|
+## Problem
|
|
|
+
|
|
|
+There were a number of gaps found in the design when @zygoloid went to implement
|
|
|
+these features in [the explorer codebase](/explorer), for example
|
|
|
+[#1311: Basic support for `.Self` within `:!` bindings and `where` expressions](https://github.com/carbon-language/carbon-lang/pull/1311).
|
|
|
+
|
|
|
+## Background
|
|
|
+
|
|
|
+`Self` was introduced for interfaces and implementations in
|
|
|
+[#524: Generics overview](https://github.com/carbon-language/carbon-lang/pull/524)
|
|
|
+and
|
|
|
+[#553: Generics details part 1](https://github.com/carbon-language/carbon-lang/pull/553).
|
|
|
+`Self` was introduced for class types and methods in
|
|
|
+[#494: Method syntax](https://github.com/carbon-language/carbon-lang/issues/494)
|
|
|
+and
|
|
|
+[#722: Nominal classes and methods](https://github.com/carbon-language/carbon-lang/pull/722).
|
|
|
+
|
|
|
+Constraints using `where` and `.Self` were introduced in
|
|
|
+[#818: Constraints for generics (generics details 3)](https://github.com/carbon-language/carbon-lang/pull/818).
|
|
|
+The use of `where` to set associated types was introduced in
|
|
|
+[#1013: Generics: Set associated constants using `where` constraints](https://github.com/carbon-language/carbon-lang/pull/1013).
|
|
|
+
|
|
|
+The type of `.Self` and where it would be introduced grammatically was discussed
|
|
|
+[#generics channel on Discord on 2022-06-07](https://discord.com/channels/655572317891461132/708431657849585705/1013904969335836732).
|
|
|
+
|
|
|
+## Proposal
|
|
|
+
|
|
|
+This proposal implements a number of changes and clarifications about the use of
|
|
|
+`Self` and `.Self` with generics:
|
|
|
+
|
|
|
+- `Self` is now a keyword, and may not be used as an identifier even in
|
|
|
+ contexts where `Self` has no meaning. If `Self` is used in a C++ API, Carbon
|
|
|
+ will use the same mechanism for interop as other Carbon keywords.
|
|
|
+- Clarify that `Self` always refers to the current type, even for virtual
|
|
|
+ functions implemented in a derived class, not the type implementing the
|
|
|
+ method.
|
|
|
+- `Self` in an `impl` declaration may be used after the `as` to refer to the
|
|
|
+ type being implemented. This could be the type named before `as` when
|
|
|
+ specified, otherwise it is the enclosing type.
|
|
|
+- Clarify that `.Self` is legal after `:!` and `where`, as long as it only
|
|
|
+ refers to a single type variable.
|
|
|
+- Specify the type of `.Self` as `Type` after `:!`, or `MyConstraint` after
|
|
|
+ `MyConstraint where`.
|
|
|
+
|
|
|
+In addition, this proposal specifies that `where` is not an associative
|
|
|
+operator.
|
|
|
+
|
|
|
+## Details
|
|
|
+
|
|
|
+`Self` was added as a keyword to
|
|
|
+[`docs/design/lexical_conventions/words.md`](/docs/design/lexical_conventions/words.md).
|
|
|
+The other rules were added to
|
|
|
+[`docs/design/classes.md`](/docs/design/classes.md) and
|
|
|
+[`docs/design/generics/details.md`](/docs/design/generics/details.md).
|
|
|
+
|
|
|
+## Rationale
|
|
|
+
|
|
|
+This proposal fills in gaps with an aim to make things consistent and simplify
|
|
|
+by having fewer rules where possible. For example, the rule saying that it is an
|
|
|
+error if `.Self` could mean two different things is consistent with other name
|
|
|
+lookup rules, such as those from
|
|
|
+[#989: Member access expressions](https://github.com/carbon-language/carbon-lang/pull/989)
|
|
|
+and
|
|
|
+[#2070: Always `==` not `=` in `where` clauses](https://github.com/carbon-language/carbon-lang/pull/2070).
|
|
|
+Simplicity benefits Carbon's
|
|
|
+[language tools and ecosystem](/docs/project/goals.md#language-tools-and-ecosystem)
|
|
|
+and consistency leads to
|
|
|
+[code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write).
|
|
|
+
|
|
|
+## Alternatives considered
|
|
|
+
|
|
|
+### `Self` not a keyword
|
|
|
+
|
|
|
+An alternative considered was forbidding identifiers to be equal to `Self`. The
|
|
|
+big concern with that approach is that we would need some other way to
|
|
|
+interoperate with C++ code, particularly classes, that had a `Self` member. If
|
|
|
+we were adding `Self` to the language later as part of evolution, we would make
|
|
|
+it a keyword. That would allow us to use the same evolution strategy as other
|
|
|
+keywords -- we would automatically update the code to change existing uses of
|
|
|
+`Self` to the raw identifier syntax.
|
|
|
+
|
|
|
+Note that at this time
|
|
|
+[no raw identifier syntax has been approved](https://github.com/carbon-language/carbon-lang/pull/93),
|
|
|
+but Rust uses a `r#` prefix. If Carbon used the same syntax, existing uses of
|
|
|
+`Self` would be changed to `r#Self`, and so `r#Self` should still be a legal
|
|
|
+identifier.
|
|
|
+
|
|
|
+### Make `Self` a member of all types
|
|
|
+
|
|
|
+We considered making `Self` a member of all types. From this uses of `Self` and
|
|
|
+`.Self` would follow naturally. It would have other consequences as well:
|
|
|
+
|
|
|
+- `T.Self == T` for all types `T`.
|
|
|
+- `x.Self`, where `x` is a non-type value with type `T`, would be `T`. This is
|
|
|
+ because under the normal member-access rules, since `Self` is not a member
|
|
|
+ of `x`, it would look in `T` and find `T.Self`.
|
|
|
+
|
|
|
+This raised the question of whether `Self` is a member of type-of-types like
|
|
|
+`Type`. That would seem to introduce an ambiguity for `i32.Self`. Furthermore,
|
|
|
+using `x.Self` to get the type of `x` seemed tricky, it would be better to have
|
|
|
+something that used the word "type" to do that.
|
|
|
+
|
|
|
+Since [`Self` is a keyword](#self-not-a-keyword), we don't need to make it
|
|
|
+follow the normal member-access rules. So we instead only define what it means
|
|
|
+in places where we have a use case.
|
|
|
+
|
|
|
+This was discussed
|
|
|
+[on 2022-08-29 in the #typesystem channel in Discord](https://discord.com/channels/655572317891461132/708431657849585705/1013904969335836732).
|
|
|
+
|
|
|
+### `where` operator could be associative
|
|
|
+
|
|
|
+We considered making the `where` operator associative, since an expression like
|
|
|
+
|
|
|
+```
|
|
|
+Interface1 where .AssocType1 is Interface2 where .AssocType2 == i32
|
|
|
+```
|
|
|
+
|
|
|
+would more usefully be interpreted as:
|
|
|
+
|
|
|
+```
|
|
|
+Interface1 where .AssocType1 is (Interface2 where .AssocType2 == i32)
|
|
|
+```
|
|
|
+
|
|
|
+than the alternative. However, this is expected to be a rare case and so it
|
|
|
+seemed much friendlier to humans to require parentheses or a separate named
|
|
|
+constraint declaration. This way they can easily visually disambiguate how it is
|
|
|
+interpreted without having to remember a rule that won't commonly be relevant.
|
|
|
+
|
|
|
+This was discussed in
|
|
|
+[the #syntax channel on Discord on 2022-05-27](https://discord.com/channels/655572317891461132/709488742942900284/979869282903130153)
|
|
|
+and
|
|
|
+[the weekly sync meeting on 2022-06-01](https://docs.google.com/document/d/1dwS2sJ8tsN3LwxqmZSv9OvqutYhP71dK9Dmr1IXQFTs/edit?resourcekey=0-NxBWgL9h05yD2GOR3wUisg#heading=h.qarzfirrcrgf).
|