Skip to content

Commit 2b53a8b

Browse files
sjrdKordyjan
authored andcommitted
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]
1 parent 6fb812a commit 2b53a8b

File tree

4 files changed

+37
-68
lines changed

4 files changed

+37
-68
lines changed

docs/_spec/06-expressions.md

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,9 @@ An application `´f(e_1, ..., e_m)´` applies the method `´f´` to the argument
205205
For this expression to be well-typed, the method must be *applicable* to its arguments:
206206

207207
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)´.
209209
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.
210211
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´`.
211212

212213
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:
@@ -681,7 +682,8 @@ Expr1 ::= ‘if’ ‘(’ Expr ‘)’ {nl} Expr [[semi] ‘else’ E
681682
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´.
682683
The condition ´e_1´ is expected to conform to type `Boolean`.
683684
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.
685687
A semicolon preceding the `else` symbol of a conditional expression is ignored.
686688

687689
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
883885
Let ´\mathit{pt}´ be the expected type of the try expression.
884886
The block ´b´ is expected to conform to ´\mathit{pt}´.
885887
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´.
887889

888890
A try expression `try { ´b´ } finally ´e´` evaluates the block ´b´.
889891
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
10421044

10431045
Evaluation of a statement sequence entails evaluation of the statements in the order they are written.
10441046

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+
10451070
## Implicit Conversions
10461071

10471072
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
10631088

10641089
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´]`.
10651090

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.
10711093

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.
10741095

10751096
###### Value Discarding
10761097
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´; () }`.

docs/_spec/08-pattern-matching.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,8 @@ If no such bounds can be found, a compile time error results.
518518
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´.
519519

520520
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.
522523

523524
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).
524525
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
595596
```
596597

597598
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´.
599600

600601
```scala
601602
new scala.Function´k´[´S_1, ..., S_k´, ´T´] {
@@ -619,7 +620,7 @@ new scala.PartialFunction[´S´, ´T´] {
619620
}
620621
```
621622

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´.
623624
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.
624625

625626
###### Example

docs/_spec/TODOreference/dropped-features/weak-conformance.md renamed to docs/_spec/APPLIEDreference/dropped-features/weak-conformance.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ Therefore, Scala 3 drops the general notion of weak conformance, and
4444
instead keeps one rule: `Int` literals are adapted to other numeric
4545
types if necessary.
4646

47-
[More details](weak-conformance-spec.md)
47+
For more details, see Sections "Types > Weak Conformance" and "Expressions > Harmonization" in the specification.
48+
TODO Link to the spec when it is published.

docs/_spec/TODOreference/dropped-features/weak-conformance-spec.md

Lines changed: 0 additions & 54 deletions
This file was deleted.

0 commit comments

Comments
 (0)