Closed rethab closed 7 years ago
Thanks @rethab , report confirmed.
Note that following code type checks without problem -- seems related to REPL:
object Foo {
def id(x: 1): 1 = x
def f = id(1)
id(1)
}
I have analyzed this a little.
What I have noticed is that in Typer.scala:1841 where the types are compared
else if (tree.tpe <:< pt) {
it returns false when my code from the first example is run in the REPL, but it returns true if the example from @liufengyun is run (ie. w/o REPL).
Actually, in both cases both sides are equal (ConstantType(Constant(4))
) however in the REPL, the two don't refer to the same object in memory whereas otherwise they do. It seems that the TypeComparer
doesn't return true unless they point to the same object in memory.
My assumption is that the types are usually cached, but not between runs in the REPL. This is supported by the following snippet, which works in the REPL:
scala> def id(x: 4): 4 = x; id(4)
def id(x: 4.type): Int(4)
What I am unsure about is whether all types are always supposed to be cached and therefore the REPL needs to ensure that it re-uses types between runs (ie. several evaluated lines) or the TypeComparer
should return true in topLevelSubType
if they are the same but don't point to the same object.
Thanks for the analysis! TypeComparer
should not rely on type caching. To me it looks the subtyping checks done by firstTry
, secondTry
, etc are missing cases for ConstantType
I would try adding handling of tp1
being a ConstantType
and tp2
being a ConstantType
to firstTry
. If that works, you can do some more testing to make sure things work as expected when you have a type alias of a constant type, an abstract type upper-bounded by a constant type, a type parameter which is a constant type, etc. You can test all of this using the REPL and add the output as tests in tests/repl/
Ok, thanks for the hints. I'll first have to invest some time to understand how the whole thing works down there.
Are there no unit tests for the single components such as the TypeComparer
? I can surely test this from the REPL, but the issue isn't really with the REPL -- as you are saying.
Ok, thanks for the hints. I'll first have to invest some time to understand how the whole thing works down there.
Here are some tips: you can run the compiler or the repl with -explaintypes
to see a small subtyping tests trace when a type mismatch error happens. You can see every subtyping check by setting val subtyping
to be equal to new Printer
instead of noPrinter
in https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/config/Printers.scala and by running the compiler or the repl with -Ylog:all
(this will log all phases, you can also just use -Ylog:frontend
since the frontend phase is when we do the initial typechecking). Although this may be a lot of information and it might be easier to try to do the fix without thinking about everything that is going on ;).
Are there no unit tests for the single components such as the TypeComparer?
Not for TypeComparer, we don't have muxh unit tests at that level.
(Also have a look at http://dotty.epfl.ch/docs/contributing/workflow.html if you haven't already)
Thanks a lot! I'm actually mostly using the debugger to step through and try to make sense out of it :)
As the below example shows, a method that takes a singleton type
Int(1)
cannot be applied with1
.