Skip to content

Commit 944b6b3

Browse files
authored
Merge pull request #6417 from dotty-staging/try-contextual-delegate
Fixes to repr and implicit trials
2 parents 1e471fa + 9a038f9 commit 944b6b3

17 files changed

+40
-39
lines changed

docs/docs/reference/contextual-implicit/inferable-by-name-parameters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The precise steps for synthesizing an argument for a by-name parameter of type `
4040
```
4141
where `lv` is an arbitrary fresh name.
4242

43-
1. This implicit is not immediately available as candidate for argument inference (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an implicit argument to a by-name parameter.
43+
1. This implicit is not immediately available as a candidate for argument inference (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an implicit argument to a by-name parameter.
4444

4545
1. If this search succeeds with expression `E`, and `E` contains references to the implicit `lv`, replace `E` by
4646

docs/docs/reference/contextual-implicit/inferable-params.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ max(List(1, 2, 3), Nil)
3030

3131
## Anonymous Implicit Parameters
3232

33-
In many situations, the name of an implicit parameter of a method need not be mentioned explicitly at all, since it is only used as synthesized implicit for other constraints. In that case one can avoid defining a parameter name and just provide its type. Example:
33+
In many situations, the name of an implicit parameter of a method need not be mentioned explicitly at all, since it is only used as a synthesized argument for other implicit parameters. In that case one can avoid defining a parameter name and just provide its type. Example:
3434
```scala
3535
def maximum[T](xs: List[T]) given Ord[T]: T =
3636
xs.reduceLeft(max)

docs/docs/reference/contextual-implicit/instance-defs.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ The name of an implicit instance can be left out. So the implicit instance defin
4141
of the last section can also be expressed like this:
4242
```scala
4343
implicit for Ord[Int] { ... }
44-
implicit [T] or Ord[List[T]] given (ord: Ord[T]) { ... }
44+
implicit [T] for Ord[List[T]] given (ord: Ord[T]) { ... }
4545
```
4646
If the name of an implicit is missing, the compiler will synthesize a name from
4747
the type(s) in the `for` clause.
4848

4949
## Alias Implicits
5050

51-
An alias implicit defines an implicit value that is equal to some expression. E.g.:
51+
An alias can be used to define an implicit value that is equal to some expression. E.g.:
5252
```scala
5353
implicit global for ExecutionContext = new ForkJoinPool()
5454
```

docs/docs/reference/contextual-implicit/multiversal-equality.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ that derives `Eql`, e.g.
3131
```scala
3232
class T derives Eql
3333
```
34-
Alternatively, one can also provide an `Eql` implicit directly, like this:
34+
Alternatively, one can also define an `Eql` implicit directly, like this:
3535
```scala
3636
implicit for Eql[T, T] = Eql.derived
3737
```
@@ -141,7 +141,7 @@ The `Eql` object defines implicits for comparing
141141
- `java.lang.Number`, `java.lang.Boolean`, and `java.lang.Character`,
142142
- `scala.collection.Seq`, and `scala.collection.Set`.
143143

144-
Implicits are defined so that every one of these types is has a reflexive `Eql` implicit, and the following holds:
144+
Implicits are defined so that every one of these types has a reflexive `Eql` implicit, and the following holds:
145145

146146
- Primitive numeric types can be compared with each other.
147147
- Primitive numeric types can be compared with subtypes of `java.lang.Number` (and _vice versa_).

docs/docs/reference/contextual-implicit/query-types-spec.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,4 @@ Gist](https://gist.github.com/OlivierBlanvillain/234d3927fe9e9c6fba074b53a7bd9
7676

7777
### Type Checking
7878

79-
After desugaring no additional typing rules are required for context query types.
79+
After desugaring no additional typing rules are required for implicit function types.

docs/docs/reference/contextual-implicit/relationship-implicits.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ one can write
140140

141141
### Implicit Classes
142142

143-
Implicit classes in Scala 2 are often used to define extension methods, which are directly supported in Dotty. Other uses of implicit classes can be simulated by a pair of a regular class and a conversion delegate.
143+
Implicit classes in Scala 2 are often used to define extension methods, which are directly supported in Dotty. Other uses of implicit classes can be simulated by a pair of a regular class and a conversion instance.
144144

145145
### Abstract Implicits
146146

147-
An abstract implicit `val` or `def` in Scala 2 can be expressed in Dotty using a regular abstract definition and an implicit alias. E.g., Scala 2's
147+
An abstract implicit `val` or `def` in Scala 2 can be expressed in Dotty using a regular abstract definition and an alias implicit. E.g., Scala 2's
148148
```scala
149149
implicit def symDeco: SymDeco
150150
```

docs/docs/reference/contextual-repr/derivation.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ enum Tree[T] derives Eql, Ordering, Pickling {
1010
case Leaf(elem: T)
1111
}
1212
```
13-
The `derives` clause generates repr representatives of the `Eql`, `Ordering`, and `Pickling` traits in the companion object `Tree`:
13+
The `derives` clause generates representatives of the `Eql`, `Ordering`, and `Pickling` traits in the companion object `Tree`:
1414
```scala
1515
repr [T: Eql] of Eql[Tree[T]] = Eql.derived
1616
repr [T: Ordering] of Ordering[Tree[T]] = Ordering.derived
@@ -19,7 +19,7 @@ repr [T: Pickling] of Pickling[Tree[T]] = Pickling.derived
1919

2020
### Deriving Types
2121

22-
Besides for `enums`, typeclasses can also be derived for other sets of classes and objects that form an algebraic data type. These are:
22+
Besides for enums, typeclasses can also be derived for other sets of classes and objects that form an algebraic data type. These are:
2323

2424
- individual case classes or case objects
2525
- sealed classes or traits that have only case classes and case objects as children.
@@ -93,8 +93,7 @@ is represented as `T *: Unit` since there is no direct syntax for such tuples: `
9393

9494
### The Generic Typeclass
9595

96-
For every class `C[T_1,...,T_n]` with a `derives` clause, the compiler generates in the companion object of `C` an representative of `Generic[C[T_1,...,T_n]]` that follows
97-
the outline below:
96+
For every class `C[T_1,...,T_n]` with a `derives` clause, the compiler generates in the companion object of `C` a representative of `Generic[C[T_1,...,T_n]]` that follows the outline below:
9897
```scala
9998
repr [T_1, ..., T_n] of Generic[C[T_1,...,T_n]] {
10099
type Shape = ...
@@ -215,7 +214,7 @@ trait Eql[T] {
215214
}
216215
```
217216
We need to implement a method `Eql.derived` that produces a representative of `Eql[T]` provided
218-
there exists evidence of type `Generic[T]`. Here's a possible solution:
217+
there exists a representative of type `Generic[T]`. Here's a possible solution:
219218
```scala
220219
inline def derived[T] given (ev: Generic[T]): Eql[T] = new Eql[T] {
221220
def eql(x: T, y: T): Boolean = {
@@ -234,7 +233,7 @@ there exists evidence of type `Generic[T]`. Here's a possible solution:
234233
The implementation of the inline method `derived` creates a representative of `Eql[T]` and implements its `eql` method. The right-hand side of `eql` mixes compile-time and runtime elements. In the code above, runtime elements are marked with a number in parentheses, i.e
235234
`(1)`, `(2)`, `(3)`. Compile-time calls that expand to runtime code are marked with a number in brackets, i.e. `[4]`, `[5]`. The implementation of `eql` consists of the following steps.
236235

237-
1. Map the compared values `x` and `y` to their mirrors using the `reflect` method of the implicitly passed `Generic` evidence `(1)`, `(2)`.
236+
1. Map the compared values `x` and `y` to their mirrors using the `reflect` method of the implicitly passed `Generic` `(1)`, `(2)`.
238237
2. Match at compile-time against the shape of the ADT given in `ev.Shape`. Dotty does not have a construct for matching types directly, but we can emulate it using an `inline` match over an `erasedValue`. Depending on the actual type `ev.Shape`, the match will reduce at compile time to one of its two alternatives.
239238
3. If `ev.Shape` is of the form `Cases[alts]` for some tuple `alts` of alternative types, the equality test consists of comparing the ordinal values of the two mirrors `(3)` and, if they are equal, comparing the elements of the case indicated by that ordinal value. That second step is performed by code that results from the compile-time expansion of the `eqlCases` call `[4]`.
240239
4. If `ev.Shape` is of the form `Case[elems]` for some tuple `elems` for element types, the elements of the case are compared by code that results from the compile-time expansion of the `eqlElems` call `[5]`.
@@ -302,7 +301,7 @@ The last, and in a sense most interesting part of the derivation is the comparis
302301
case ev: Eql[T] =>
303302
ev.eql(x, y) // (15)
304303
case _ =>
305-
error("No `Eql` representative was found for $T")
304+
error("No `Eql` instance was found for $T")
306305
}
307306
```
308307
`tryEql` is an inline method that takes an element type `T` and two element values of that type as arguments. It is defined using an `implicit match` that tries to find a representative of `Eql[T]`. If a representative `ev` is found, it proceeds by comparing the arguments using `ev.eql`. On the other hand, if no representative is found

docs/docs/reference/contextual-repr/extension-methods.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Then
5656
```scala
5757
List("here", "is", "a", "list").longestStrings
5858
```
59-
is legal everywhere `ops1` is available as a representative. Alternatively, we can define `longestStrings` as a member of a normal object. But then the method has to be brought into scope to be usable as an extension method.
59+
is legal everywhere `ops1` is eligible. Alternatively, we can define `longestStrings` as a member of a normal object. But then the method has to be brought into scope to be usable as an extension method.
6060

6161
```scala
6262
object ops2 extends StringSeqOps
@@ -80,7 +80,7 @@ So `circle.circumference` translates to `CircleOps.circumference(circle)`, provi
8080

8181
### Representatives for Extension Methods
8282

83-
Representatives that define extension methods can also be defined without a `for` clause. E.g.,
83+
Representatives that define extension methods can also be defined without an `of` clause. E.g.,
8484

8585
```scala
8686
repr StringOps {
@@ -94,12 +94,12 @@ repr {
9494
def (xs: List[T]) second[T] = xs.tail.head
9595
}
9696
```
97-
If such representatives are anonymous (as in the second clause), their name is synthesized from the name
97+
If such a representative is anonymous (as in the second clause), its name is synthesized from the name
9898
of the first defined extension method.
9999

100100
### Operators
101101

102-
The extension method syntax also applies to the definitions of operators.
102+
The extension method syntax also applies to the definition of operators.
103103
In each case the definition syntax mirrors the way the operator is applied.
104104
Examples:
105105
```scala

docs/docs/reference/contextual-repr/import-implied.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ object B {
1818
In the code above, the `import A._` clause of object `B` will import all members
1919
of `A` _except_ the representative `tc`. Conversely, the second import `import repr A._` will import _only_ that representative.
2020

21-
Generally, a normal import clause brings all definitions except representatives into scope whereas an `import repr` clause brings only representatives into scope.
21+
Generally, a normal import clause brings all members except representatives into scope whereas an `import repr` clause brings only representatives into scope.
2222

2323
There are two main benefits arising from these rules:
2424

@@ -29,7 +29,7 @@ There are two main benefits arising from these rules:
2929
can be anonymous, so the usual recourse of using named imports is not
3030
practical.
3131

32-
### Relationship with Old-Style Implicits
32+
### Migration
3333

3434
The rules of representatives above have the consequence that a library
3535
would have to migrate in lockstep with all its users from old style implicits and
@@ -49,4 +49,4 @@ The following modifications avoid this hurdle to migration.
4949

5050
These rules mean that library users can use `import repr` to access old-style implicits in Scala 3.0,
5151
and will be gently nudged and then forced to do so in later versions. Libraries can then switch to
52-
representation clauses once their user base has migrated.
52+
`repr` clauses once their user base has migrated.

docs/docs/reference/contextual-repr/inferable-by-name-parameters.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ The precise steps for synthesizing an argument for a by-name parameter of type `
4040
```
4141
where `lv` is an arbitrary fresh name.
4242

43-
1. This representative is not immediately available as candidate for argument inference (making it immediately available could result in a loop in the synthesized computation). But it becomes available in all nested contexts that look again for an argument to an implicit by-name parameter.
43+
1. This representative is not immediately eligible as a candidate for argument inference (making it immediately eligible could result in a loop in the synthesized computation). But it becomes eligible in all nested contexts that look again for an implicit argument to a by-name parameter.
4444

4545
1. If this search succeeds with expression `E`, and `E` contains references to the representative `lv`, replace `E` by
4646

0 commit comments

Comments
 (0)