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
Spec: Apply changes to weak conformance and introduce harmonization.
Note that weak conformance was not entirely dropped. It is still
applicable to determine *compatibility* of a method call argument
to the parameter type.
[Cherry-picked 3f3423f]
Copy file name to clipboardExpand all lines: docs/_spec/06-expressions.md
+31-10Lines changed: 31 additions & 10 deletions
Original file line number
Diff line number
Diff line change
@@ -205,8 +205,9 @@ An application `´f(e_1, ..., e_m)´` applies the method `´f´` to the argument
205
205
For this expression to be well-typed, the method must be *applicable* to its arguments:
206
206
207
207
If ´f´ has a method type `(´p_1´:´T_1, ..., p_n´:´T_n´)´U´`, each argument expression ´e_i´ is typed with the corresponding parameter type ´T_i´ as expected type.
208
-
Let ´S_i´ be the type of argument ´e_i´ ´(i = 1, ..., m)´.
208
+
Let ´S_i´ be the type of argument ´e_i´ ´(i = 1, ..., n)´.
209
209
The method ´f´ must be _applicable_ to its arguments ´e_1, ..., e_n´ of types ´S_1, ..., S_n´.
210
+
If the last parameter type of ´f´ is [repeated](04-basic-declarations-and-definitions.html#repeated-parameters), [harmonization](#harmonization) is attempted on the suffix ´e_m, ..., e_n´ of the expression list that match the repeated parameter.
210
211
We say that an argument expression ´e_i´ is a _named_ argument if it has the form `´x_i=e'_i´` and `´x_i´` is one of the parameter names `´p_1, ..., p_n´`.
211
212
212
213
Once the types ´S_i´ have been determined, the method ´f´ of the above method type is said to be applicable if all of the following conditions hold:
The _conditional expression_`if (´e_1´) ´e_2´ else ´e_3´` chooses one of the values of ´e_2´ and ´e_3´, depending on the value of ´e_1´.
682
683
The condition ´e_1´ is expected to conform to type `Boolean`.
683
684
The then-part ´e_2´ and the else-part ´e_3´ are both expected to conform to the expected type of the conditional expression.
684
-
The type of the conditional expression is the [weak least upper bound](03-types.html#weak-conformance) of the types of ´e_2´ and ´e_3´.
685
+
If there is no expected type, [harmonization](#harmonization) is attempted on ´e_2´ and ´e_3´.
686
+
The type of the conditional expression is the [least upper bound](03-types.html#least-upper-bounds-and-greatest-lower-bounds) of the types of ´e_2´ and ´e_3´ after harmonization.
685
687
A semicolon preceding the `else` symbol of a conditional expression is ignored.
686
688
687
689
The conditional expression is evaluated by evaluating first ´e_1´.
@@ -883,7 +885,7 @@ More generally, if the handler is a `PartialFunction`, it is applied only if it
883
885
Let ´\mathit{pt}´ be the expected type of the try expression.
884
886
The block ´b´ is expected to conform to ´\mathit{pt}´.
885
887
The handler ´h´ is expected conform to type `scala.Function[scala.Throwable, ´\mathit{pt}\,´]`.
886
-
The type of the try expression is the [weak least upper bound](03-types.html#weak-conformance) of the type of ´b´ and the result type of ´h´.
888
+
The type of the try expression is the [least upper bound](03-types.html#least-upper-bounds-and-greatest-lower-bounds) of the type of ´b´ and the result type of ´h´.
887
889
888
890
A try expression `try { ´b´ } finally ´e´` evaluates the block ´b´.
889
891
If evaluation of ´b´ does not cause an exception to be thrown, the expression ´e´ is evaluated.
@@ -1042,6 +1044,29 @@ When prefixing a class or object definition, modifiers `abstract`, `final`, and
1042
1044
1043
1045
Evaluation of a statement sequence entails evaluation of the statements in the order they are written.
1044
1046
1047
+
## Harmonization
1048
+
1049
+
_Harmonization_ of a list of expressions tries to adapt `Int` literals to match the types of sibling trees.
1050
+
For example, when writing
1051
+
1052
+
```scala
1053
+
scala.collection.mutable.ArrayBuffer(5.4, 6, 6.4)
1054
+
```
1055
+
1056
+
the inferred element type would be `AnyVal` without harmonization.
1057
+
Harmonization turns the integer literal `6` into the double literal `6.0` so that the element type becomes `Double`.
1058
+
1059
+
Formally, given a list of expressions ´e_1, ..., e_n´ with types ´T_1, ..., T_n´, harmonization behaves as follows:
1060
+
1061
+
1. If there is an expected type, return the original list.
1062
+
2. Otherwise, if there exists ´T_i´ that is not a primitive numeric type (`Char`, `Byte`, `Short`, `Int`, `Long`, `Float`, `Double`), return the original list.
1063
+
3. Otherwise,
1064
+
1. Partition the ´e_i´ into the integer literals ´f_j´ and the other expressions ´g_k´.
1065
+
2. If all the ´g_k´ have the same numeric type ´T´, possibly after widening, and if all the integer literals ´f_j´ can be converted without loss of precision to ´T´, return the list of ´e_i´ where every int literal is converted to ´T´.
1066
+
3. Otherwise, return the original list.
1067
+
1068
+
Harmonization is used in [conditional expressions](#conditional-expressions) and [pattern matches](./08-pattern-matching.html), as well as in [local type inference](#local-type-inference).
1069
+
1045
1070
## Implicit Conversions
1046
1071
1047
1072
Implicit conversions can be applied to expressions whose type does not match their expected type, to qualifiers in selections, and to unapplied methods.
@@ -1063,14 +1088,10 @@ An expression ´e´ of polymorphic type
1063
1088
1064
1089
which does not appear as the function part of a type application is converted to a type instance of ´T´ by determining with [local type inference](#local-type-inference) instance types `´T_1, ..., T_n´` for the type variables `´a_1, ..., a_n´` and implicitly embedding ´e´ in the [type application](#type-applications)`´e´[´T_1, ..., T_n´]`.
1065
1090
1066
-
###### Numeric Widening
1067
-
If ´e´ has a primitive number type which [weakly conforms](03-types.html#weak-conformance) to the expected type, it is widened to the expected type using one of the numeric conversion methods `toShort`, `toChar`, `toInt`, `toLong`, `toFloat`, `toDouble` defined [in the standard library](12-the-scala-standard-library.html#numeric-value-types).
1068
-
1069
-
Since conversions from `Int` to `Float` and from `Long` to `Float` or `Double` may incur a loss of precision, those implicit conversions are deprecated.
1070
-
The conversion is permitted for literals if the original value can be recovered, that is, if conversion back to the original type produces the original value.
1091
+
###### Numeric Literal Conversion
1092
+
If the expected type is `Byte`, `Short`, `Long` or `Char`, and the expression ´e´ is an `Int` literal fitting in the range of that type, it is converted to the same literal in that type.
1071
1093
1072
-
###### Numeric Literal Narrowing
1073
-
If the expected type is `Byte`, `Short` or `Char`, and the expression ´e´ is an integer literal fitting in the range of that type, it is converted to the same literal in that type.
1094
+
Likewise, if the expected type is `Float` or `Double`, and the expression ´e´ is a numeric literal (of any type) fitting in the range of that type, it is converted to the same literal in that type.
1074
1095
1075
1096
###### Value Discarding
1076
1097
If ´e´ has some value type and the expected type is `Unit`, ´e´ is converted to the expected type by embedding it in the term `{ ´e´; () }`.
Copy file name to clipboardExpand all lines: docs/_spec/08-pattern-matching.md
+4-3Lines changed: 4 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -518,7 +518,8 @@ If no such bounds can be found, a compile time error results.
518
518
If such bounds are found, the pattern matching clause starting with ´p´ is then typed under the assumption that each ´a_i´ has lower bound ´L_i'´ instead of ´L_i´ and has upper bound ´U_i'´ instead of ´U_i´.
519
519
520
520
The expected type of every block ´b_i´ is the expected type of the whole pattern matching expression.
521
-
The type of the pattern matching expression is then the [weak least upper bound](03-types.html#weak-conformance) of the types of all blocks ´b_i´.
521
+
If there is no expected type, [harmonization](./03-types.html#harmonization) is attempted on the list of all blocks ´b_i´.
522
+
The type of the pattern matching expression is then the [least upper bound](03-types.html#least-upper-bounds-and-greatest-lower-bounds) of the types of all blocks ´b_i´ after harmonization.
522
523
523
524
When applying a pattern matching expression to a selector value, patterns are tried in sequence until one is found which matches the [selector value](#patterns).
524
525
Say this case is `case ´p_i \Rightarrow b_i´`.
@@ -595,7 +596,7 @@ If the expected type is [SAM-convertible](06-expressions.html#sam-conversion) to
595
596
```
596
597
597
598
Here, each ´x_i´ is a fresh name.
598
-
As was shown [here](06-expressions.html#anonymous-functions), this anonymous function is in turn equivalent to the following instance creation expression, where ´T´ is the weak least upper bound of the types of all ´b_i´.
599
+
As was shown [here](06-expressions.html#anonymous-functions), this anonymous function is in turn equivalent to the following instance creation expression, where ´T´ is the least upper bound of the types of all ´b_i´.
599
600
600
601
```scala
601
602
new scala.Function´k´[´S_1, ..., S_k´, ´T´] {
@@ -619,7 +620,7 @@ new scala.PartialFunction[´S´, ´T´] {
619
620
}
620
621
```
621
622
622
-
Here, ´x´ is a fresh name and ´T´ is the weak least upper bound of the types of all ´b_i´.
623
+
Here, ´x´ is a fresh name and ´T´ is the least upper bound of the types of all ´b_i´.
623
624
The final default case in the `isDefinedAt` method is omitted if one of the patterns ´p_1, ..., p_n´ is already a variable or wildcard pattern.
0 commit comments