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
- Dependent methods cannot be called via structural call.
88
-
- Overloaded methods cannot be called via structural call.
89
-
- Refinements do not handle polymorphic methods.
90
88
91
-
## Differences with Scala 2 structural types
89
+
- Refinements may not introduce overloads: If a refinement specifies the signature
90
+
of a method `m`, and `m` is also defined in the parent type of the refinement, then
91
+
the new signature must properly override the existing one.
92
+
93
+
- Subtyping of structural refinements must preserve erased parameter types: Assume
94
+
we want to prove `S <: T { def m(x: A): B }`. Then, as usual, `S` must have a member method `m` that can take an argument of type `A`. Furthermore, if `m` is not a member of `T` (i.e. the refinement is structural), an additional condition applies. In this case, the member _definition_`m` of `S` will have a parameter
95
+
with type `A'` say. The additional condition is that the erasure of `A'` and `A` is the same. Here is an example:
96
+
97
+
```scala
98
+
classSink[A] { defput(x: A):Unit= {} }
99
+
vala=Sink[String]()
100
+
valb: { defput(x: String):Unit } = a // error
101
+
b.put("abc") // looks for a method with a `String` parameter
102
+
```
103
+
The second to last line is not well-typed, since the erasure of the parameter type of `put` in class `Sink` is `Object`, but the erasure of the refinement of the type of `b` is `String`. This additional condition is necessary, since we will have to resort to reflection to call a structural member like `put` in the type of `b` above. The condition ensures that the statically known parameter types of the refinement correspond up to erasure to the parameter types of the selected call target at runtime.
104
+
105
+
The usual reflection dispatch algorithms need to know exact erased parameter types. For instance, if the example above would typecheck, the call
106
+
`b.put("abc")` on the last line would look for a method `put` in the runtime type of `b` that takes a `String` parameter. But the `put` method is the one from class `Sink`, which takes an `Object` parameter. Hence the call would fail at runtime with a `NoSuchMethodException`.
107
+
108
+
One might hope for a "more intelligent" reflexive dispatch algorithm that does not require exact parameter type matching. Unfortunately, this can always run into ambiguities. For instance, continuing the example above, we might introduce a new subclass `Sink1` of `Sink` and change the definition of `a` as follows:
0 commit comments