Inconsistent handling of intersections w/type parameter & upper bound constraints
Closed this issue · 6 comments
The intersection of a type parameter and its upper bound constraints simplifies to just the type parameter. For example, the intersection of T satisfies Object
and Object
(T & Object
) is "just" T
.
However, "redundant" intersection components are meaningful when substituting a type that is not a subtype of T
's upper bound constraints into T
. For example, after substituting an unconstrained U
into T
for use in the expression T & Object
, the result will be U & Object
, not "just" U
as it would be for the simplified expression T
.
The "simplification" of types like T & Object
is unintentionally material, and inconsistently performing type simplifications can produce inconsistent results.
An example of this on the JVM backend is when a type like T & Object
is used as the type of a shared
member. It is not simplified for code that is compiled at the same time, but it is simplified in the stored model used for future compiles.
The attached two-module project demonstrates this. Compiling the modules at the same time works:
$ ceylon compile
Note: Created module app/1.0.0
Note: Created module lib/1.0.0
but compiling separately fails:
$ ceylon compile lib ; ceylon compile app
Note: Created module lib/1.0.0
source/app/run.ceylon:4: error: specified type does not cover the cases of the operand expression: 'Object' does not cover 'T'
noop(c.t of Object);
^
1 error
Note: Created module app/1.0.0
ceylon compile: There was 1 error
The relevant code in module lib
is:
shared class C<T>(shared T & Object t) given T satisfies Object {}
and in app
:
import lib { C }
void f<T>(C<T> c) {
noop(c.t of Object);
}
The sample project -
bug7383.zip
This is one reason why Java infers implicit constraints for wildcards. Not saying y'all should do that - it's just interesting to see an example in practice.
So I don't know why the Java backend canonicalizes types in TypeInfo
annotations, and I think it's wrong that it does. The offending line of code is AbstractTransformer:3746
.
@jvasileff could you check that be37326 fixes the problem please?
I don't have anything except the sample project, so if ceylon compile lib && ceylon compile app
works I guess were good.
OK, @jvasileff, great, closing.