You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
*[Extended type inference algorithm](#extended-type-inference-algorithm)
43
44
*[JVM ABI and Java compatibility](#jvm-abi-and-java-compatibility)
44
45
*[Q\&A about design decisions](#qa-about-design-decisions)
45
46
*[Acknowledgments](#acknowledgments)
@@ -52,6 +53,14 @@ This document is not (yet) formally a KEEP, since it lacks some of the technical
52
53
* Within the body of the declared member, the value of the context parameter is accessible using its name, similar to value parameters.
53
54
* It is allowed to use `_` as a name; in that case, the value is not accessible through any name (but still participates in context resolution).
54
55
56
+
```kotlin
57
+
context(analysisScope:AnalysisScope)
58
+
fun Type.equalTo(other:Type): Boolean=...
59
+
60
+
context(analysisScope:AnalysisScope)
61
+
valType.isNullable:Boolean get() =...
62
+
```
63
+
55
64
**§2***(restrictions)*:
56
65
57
66
* It is an *error* to declare an **empty** list of context parameters.
@@ -106,7 +115,7 @@ withConsoleLogger {
106
115
107
116
## Standard library support
108
117
109
-
**§7***(`context` function)*: To extend the implicit scope in a contextual manner we provide additional functions in the standard library.
118
+
**§8***(`context` function)*: To extend the implicit scope in a contextual manner we provide additional functions in the standard library.
110
119
111
120
* The implementation may be built into the compiler, instead of having a plethora of functions defined in the standard library.
112
121
@@ -116,7 +125,7 @@ fun <A, B, R> context(a: A, b: B, block: context(A, B) () -> R): R = block(a, b)
116
125
fun <A, B, C, R> context(a:A, b:B, c:C, block: context(A, B, C) () ->R): R= block(a, b, c)
117
126
```
118
127
119
-
**§8***(`implicit` function)*: We also provide a generic way to obtain a value by type from the context. It allows access to context parameters even when declared using `_`, or within the body of a lambda.
128
+
**§9***(`implicit` function)*: We also provide a generic way to obtain a value by type from the context. It allows access to context parameters even when declared using `_`, or within the body of a lambda.
120
129
121
130
```kotlin
122
131
context(ctx:A) fun <A> implicit(): A= ctx
@@ -173,7 +182,7 @@ We do this by introducing a **bridge function** that simply wraps the access to
**§23***(declaration with context parameters)*: The context parameters declared for a callable are available in the same way as "regular" value parameters in the body of the function. Both value and context parameters are introduced in the same scope, there is no shadowing between them.
378
387
379
-
**§24***(function applicability)*: Building the constraint system is modified for lambda arguments. Compared with the [Kotlin specification](https://kotlinlang.org/spec/overload-resolution.html#description), the type of the parameter _U<sub>m</sub>_ is replaced with _nocontext(U<sub>m</sub>)_, where _nocontext_ removes the initial `context` block from the function type.
388
+
**§24***(applicability, lambdas)*: Building the constraint system is modified for lambda arguments. Compared with the [Kotlin specification](https://kotlinlang.org/spec/overload-resolution.html#description), the type of the parameter _U<sub>m</sub>_ is replaced with _nocontext(U<sub>m</sub>)_, where _nocontext_ removes the initial `context` block from the function type.
380
389
381
-
**§25***(most specific candidate)*: When choosing the **most specific candidate** we follow the Kotlin specification, with one addition:
390
+
**§25***(applicability, context resolution)*: After the first phase of function applicability -- checking the type constraint problem -- an additional **context resolution**phase is inserted. For each potentially applicable callable, for each context parameter, we traverse the tower of scopes looking for **exactly one** default receiver or context parameter with a compatible type.
382
391
383
-
* Candidates with context parameters are considered more specific than those without them.
384
-
* But there is no other prioritization coming from the length of the context parameter list or their types.
392
+
There are three possible outcomes of this process:
385
393
386
-
**§26***(context resolution)*: Once the overload candidate is chosen, we **resolve** context parameters (if any). For each context parameter:
394
+
1. If _no_ compatible context value is found for at least one context parameter, then the call is _not_ applicable, and it is removed from the candidate set as a result.
395
+
2. If for at least one context parameter there is more than one compatible value at the same level (and case 1 does not apply), a _context ambiguity_ error is issued.
396
+
3. If none of (1) or (2) apply, then the candidate is applicable.
387
397
388
-
* We traverse the tower of scopes looking for **exactly one** default receiver or context parameter with a compatible type.
389
-
* Anonymous context parameters (declared with `_`) also participate in this process.
390
-
* It is an ambiguity error if more than one value is found at the same level.
391
-
* It is an overload resolution error if no applicable value is found.
398
+
The following piece of code exemplifies how scoping interacts with context resolution:
with(console) { logWithTime("hello") } // no ambiguity, uses 'console'
411
418
```
412
419
420
+
**§26***(applicability, `DslMarker`)*: During context resolution, if at a certain scope there is a potential contextual value in scope (either coming from a context parameter or for implicit scope) marked with an annotation `@X` which is itself annotated with [`@DslMarker`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-dsl-marker/) then:
421
+
422
+
- It is an _error_ for two such values to be available in the same scope.
423
+
- If context resolution chooses a contextual value with the same annotation, but in an outer scope, it is a compilation _error_.
424
+
- If a call binds to a receiver with the same annotation, it is a compilation _error_.
425
+
426
+
These rules extend the usual behavior of `@DslMarker` to cover both receivers and context parameters uniformly.
427
+
428
+
**§27***(most specific candidate)*: When choosing the **most specific candidate** we follow the [Kotlin specification](https://kotlinlang.org/spec/overload-resolution.html#choosing-the-most-specific-candidate-from-the-overload-candidate-set), with one addition:
429
+
430
+
* Candidates with context parameters are considered more specific than those without them.
431
+
* But there is no other prioritization coming from the length of the context parameter list or their types.
432
+
433
+
### Extended type inference algorithm
434
+
435
+
**§28***(lambda literal inference)*: the type inference process in the [Kotlin specification](https://kotlinlang.org/spec/type-inference.html#statements-with-lambda-literals) should take context parameters into account. Note that unless a function type with context is "pushed" as a type for the lambda, context parameters are never inferred.
436
+
413
437
### JVM ABI and Java compatibility
414
438
415
-
**§27***(JVM and Java compatibility)*: In the JVM a function with context parameters is represented as a regular function with the context parameters situated at the *beginning* of the parameter list. The name of the context parameter, if present, is used as the name of the parameter.
439
+
**§29***(JVM and Java compatibility)*: In the JVM a function with context parameters is represented as a regular function with the context parameters situated at the *beginning* of the parameter list. The name of the context parameter, if present, is used as the name of the parameter.
416
440
417
441
* Note that parameter names do not impact JVM ABI compatibility.
0 commit comments