The name ComparableFromDifferenceFn comes from the next example. In this
example ComparableFromDifference is the name of the class that will be
implictly cast to a Facet matching Comparable.
Update broken links to aid in following links while perusing the
documentation. Closes#3778
I don't imagine I got every one of these right. Some 404s may be
reported due to permissions.
Using the lychee command in #3778, only the following link is reported
as not found, but it's just a permission issue:
```
[proposals/p1367.md]:
✗ [404] https://github.com/carbon-language/carbon-lang/settings/access | Failed: Network error: Not Found
```
I tried to get it down to as few as possible, partially so that future
link scans won't run into repeat errors.
---------
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
The version of `flake8` was too old to support with Python 3.12 -- there
is new F-string support that caused false positives sadly. The updated
version has fixes for all of these.
This in turn updates codespell which has picked up several new fixes
that actually fire in our code, so also fix everything. While we don't
do more in-depth updates to old proposals, similar to simply fixing
broken links, fixing automatically detected typos seems scalable and
fine.
All edits were automatically generated here.
Continued from part 1: #3231. Second step updating
`docs/design/generics/details.md`. There remains some work to
incorporate proposal #2200.
- The biggest changes are incorporating much of the text of proposals:
- #2173
- #2687
- It incorporates changes from proposals:
- #989
- #1178
- #2138
- #2200
- #2360
- #2964
- #3162
- It also updates the text to reflect the latest thinking from leads
issues:
- #996
- #2153 -- most notably deleting the section on `TypeId`.
- Update to rule for prioritization blocks with mixed type structures
from [discussion on
2023-07-18](https://docs.google.com/document/d/1gnJBTfY81fZYvI_QXjwKk1uQHYBNHGqRLI2BS_cYYNQ/edit?resourcekey=0-ql1Q1WvTcDvhycf8LbA9DQ#heading=h.7jxges9ojgy3)
- Adds reference links to proposals, issues, and discussions relevant to
the text.
- Also tries to use more precise language when talking about
implementations, to avoid confusing `impl` declaration and definitions
with the `impls` operator used in `where` clauses, an issue brought up
in
- #2495
- #2483
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
First step in updating `docs/design/generics/details.md`. It
incorporates changes from proposals: #989#2138#2173#2200#2360#2964#3162 , but there are still more changes from those proposals to be
made.
It also switches away from suggesting static-dispatch witness tables,
and creates an appendix to describe that decision.
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This reflects changes from a number of approved proposals:
- #920 : concrete statements about orphan and overlap in Carbon
- #2138 : "generic" -> "checked generic", "template" -> "template
generic"
- #2188 : binding patterns are forbidden in type position
- #2360 : "type", "facet type", "facet". Note: I am not using the term
"generic type" from #2360 since that meaning conflicts with the
generally accepted meaning of "generic type" of a type with a
compile-time parameter.
- #2760 / #2770 : internal/external impl -> extending impl
- #2964 : "symbolic constant" and "template constant"
---------
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
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
Allow an `impl` to overlap with a `final impl` if they agree on the overlap. Agreement is defined as all values comparing equal, and functions never comparing equal. Implements the decision in question-for-leads issue #1077.
Use the keyword `impls` instead of `is` when writing a `where` constraint that a type variable needs to implement an interface or named constraint.
What was previously (provisionally) written:
```
fn Sort[T:! Container where .ElementType is Ordered](x: T*);
```
will now be written:
```
fn Sort[T:! Container where .ElementType impls Ordered](x: T*);
```
---------
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Also make minor updates to the skeletal design in
docs/design/name_lookup.md following #2113, as there are no longer any prelude names that are made available to unqualified name lookup by default.
Add `type` to the keyword list in
docs/design/lexical_conventions/words.md, following #2360.
Require `impl as` constraints in an `interface` or `constraint` definition to mention `Self` implicitly or explicitly. Require `where` clauses to refer to `.Self` directly, or through a designator like `.Foo`.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
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.
The previous implementation model involved the caller of a function knowing what impls the function will need. With the addition of blanket impls and specialization to the design, that is in general no longer possible. Instead the caller provides a type which is used as a key to look up the impl, which is expected to occur during monomorphization, though we allow the compiler to employ other strategies when the set of impls is predictable.
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
This proposal:
- Adds support for interfaces requiring other types than `Self` to implement interfaces, as in:
```
interface IntLike {
impl i32 as As(Self);
// ...
}
```
- Defines requirements on how to satisfy those requirements that have a `where` clause.
- Extends `observe` declarations to include saying a type implements an interface, so code can provide a proof instead of the compiler having to perform a recursive search.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This proposal has three main contributions:
- Types with generic parameters have an identity that consists of the types names plus the values of those parameters.
- The parameters of a type may be deduced from a function's argument.
- Types with generic parameters do not support specialization. Instead, a type can delegate to an interface to opt in to allowing specific customization points.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Allow interfaces and implementations to be forward declared.
```
// Forward declare interface `F`
interface F;
class C {
// Forward declare `C` implements `F`
impl as F;
}
// Definitions corresponding to forward declarations
interface F { ... }
impl C as F { ... }
```
To allow members of interfaces with default definitions to be forward declared, prefix them with the keyword `default`, following #1082.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Operators rewrite to calls of specific operator interface functions, so you overload an operator for a type by implementing an interface for it. There is a `like` operator for defining a set if implementations for supporting implicit conversions more conveniently.
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Change the syntax for setting the associated constants and types in an interface implementation for a type from using `let` declarations as in:
```
class Vector(T:! Type) {
impl as Iterable {
let ElementType:! Type = T;
...
}
}
```
to using `where` clauses as in:
```
class Vector(T:! Type) {
impl as Iterable where .ElementType = T {
...
}
}
```
This is an attempt to simplify by removing redundancy, improve consistency by removing a use of `let` that was different than other examples, and better support forward declaration that a type implements an interface while retaining the information needed for type checking.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Allowing interfaces to define default values for its associated entities. This:
- Helps with evolution by reducing the changes needed to add new members to an interface.
- Reduces boilerplate when some value is more common than others.
- Addresses the gap between the minimum necessary for a type to provide the desired functionality of an interface and the breadth of API that user's desire.
As an alternative, final values can be provided instead, which can't be overridden, but are more predictable for users and may avoid dynamic dispatch overhead in some cases.
Example:
```
// Interface parameter has a default of `Self`
interface Add(Right:! Type = Self) {
// `AddWith` *always* equals `Right`
final let AddWith:! Type = Right;
// `Result` has a default of `Self`
let Result:! Type = Self;
fn DoAdd[me: Self](right: Right) -> Result;
}
impl String as Add() {
// Right == AddWith == Result == Self == String
fn DoAdd[me: Self](right: Self) -> Self;
}
```
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
There were some concerns about facet types leaking out of generic code in return types. Some initial fixes for this were done in [PR #900](https://github.com/carbon-language/carbon-lang/pull/900), but there remain concerns, for example when associated types are involved.
In particular, given an interface method with return type using an associated type, as in:
```
interface Deref {
let Result:! Type;
fn DoDeref[me: Self]() -> Result;
}
class IntHandle {
impl as Deref {
let Result:! Type = i32;
fn DoDeref[me: Self]() -> Result { ... }
}
}
```
Since `Result` has type `Type`, we had the problem that `IntHandle.DoDeref` would have to return `i32 as Type`, instead of the desired `i32`.
We also think we can simplify the model by eliminating the facet type concept and syntax.
This proposal removes facet types, introduces archetypes in their place, clarifies how associated types work outside of a generic function, and specifies how a generic `let` statement in a function body works.
Co-authored-by: Wolff Dobson <wolffg@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Add support for marking impls as `final` to say they can't be specialized. This allows generic functions that see that the impl applies to determine the values for its associated types. For example this allows us to say that the implementation of the `Deref` interface for pointers can't be specialized. Otherwise, `*p` could have unknown type in a generic function.
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
There are cases where an impl definition should apply to more than a single type and interface combination. The solution is to parameterize the impl definition, so it applies to a family of types, interfaces, or both. This includes:
- Declare an impl for a parameterized type, which may be external or declared out-of-line.
```
external impl [T:! Type] Vector(T) as Iterable { ... }
external impl Vector(T:! Type) as Iterable { ... }
```
- "Conditional conformance" where a parameterized type implements some interface if the parameter to the type satisfies some criteria, like implementing the same interface.
```
external impl [T:! Type] Pair(T, T) as Foo(T) { ... }
class Array(T:! Type, template N:! Int) {
impl [P:! Printable] Array(P, N) as Printable { ... }
impl Array(P:! Printable, N) as Printable { ... }
}
```
- "Blanket" impls where an interface is implemented for all types that implement another interface, or some other criteria beyond being a specific type.
```
external impl [T:! Ordered] T as PartiallyOrdered { ... }
```
- "Wildcard" impls where a family of interfaces are implemented for single type.
```
class BigInt {
external impl [T:! ImplicitAs(i32)] as AddTo(T) { ... }
external impl as AddTo(T:! ImplicitAs(i32)) { ... }
}
external impl [T:! ImplicitAs(i32)] BigInt as AddTo(T) { ... }
external impl BigInt as AddTo(T:! ImplicitAs(i32)) { ... }
```
In addition to a syntax for defining parameterized impls, we need rules for coherence:
- Orphan rules that ensure that impls are imported in any code that might use it.
- We need overlap rules that pick a specific impl when more than one impl declaration matches a specific query about whether a type implements an interface.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Implementations of interfaces are as public as the names used in their signature. No access control modifiers are allowed on `impl` declarations.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Includes a variety of changes:
Int -> i32
this -> me
expand terminology doc and add links to it
fix text to reflect inline external impl introduced in Support external impl in class and adapter scopes. #905
no longer have plans for runtime type parameters
style updates like removing parentheticals and "we"
observe is a "declaration" not a "statement", since it can appear outside function bodies
many individual updates, clean-ups, and fixes
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This proposal describes `where` clauses that can add constraints on a type-of-type, for example define restrictions on its associated types. Example:
```
fn FindFirstPrime[T:! Container where .Element = i32]
(c: T) -> Optional(i32) {
// The elements of `c` have type `T.Element`, which is `i32`.
...
}
fn PrintContainer[T:! Container where .Element is Printable](c: T) {
// The type of the elements of `c` is not known, but we do know
// that type satisfies the `Printable` interface.
...
}
```
Some other constraints, such as `Sized` are defined as type-of-types directly, possibly parameterized.
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This proposal provides an `as` expression for casting. This supports implicit conversions plus some safe and unsurprising conversions that we do not support implicitly:
* lossy but fully defined conversions to floating-point types
* conversion from `bool` to integer types
* conversion between adaptors and their adapted type, and more generally between compatible types
This facility can be extended by implementing the `As(TargetType)` interface for a type.
Co-authored-by: Geoff Romer <gromer@google.com>
Co-authored-by: josh11b <josh11b@users.noreply.github.com>