Skip to content

method with singleton type mismatches same singleton type #1702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rethab opened this issue Nov 12, 2016 · 8 comments
Closed

method with singleton type mismatches same singleton type #1702

rethab opened this issue Nov 12, 2016 · 8 comments

Comments

@rethab
Copy link
Contributor

rethab commented Nov 12, 2016

As the below example shows, a method that takes a singleton type Int(1) cannot be applied with 1.

scala> def id(x: 1): 1 = x
id: (x: Int(1))Int(1)
scala> id(1)
-- [E007] Type Mismatch Error: <console> -----------------------------------
6 |id(1)
  |   ^
  |   found:    Int(1)
  |   required: Int(1)
  |
@liufengyun
Copy link
Contributor

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)
}

@rethab
Copy link
Contributor Author

rethab commented Nov 27, 2016

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.

@smarter
Copy link
Member

smarter commented Nov 27, 2016

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

@smarter
Copy link
Member

smarter commented Nov 27, 2016

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/

@rethab
Copy link
Contributor Author

rethab commented Nov 27, 2016

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.

@smarter
Copy link
Member

smarter commented Nov 27, 2016

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.

@smarter
Copy link
Member

smarter commented Nov 27, 2016

(Also have a look at http://dotty.epfl.ch/docs/contributing/workflow.html if you haven't already)

@rethab
Copy link
Contributor Author

rethab commented Nov 27, 2016

Thanks a lot! I'm actually mostly using the debugger to step through and try to make sense out of it :)

@odersky odersky closed this as completed in 9fcc0a2 Dec 8, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants