Skip to content

Impossible to extends "Ordered" when "-Yexplicit-nulls" flag used #11341

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
flomebul opened this issue Feb 7, 2021 · 4 comments
Closed

Impossible to extends "Ordered" when "-Yexplicit-nulls" flag used #11341

flomebul opened this issue Feb 7, 2021 · 4 comments

Comments

@flomebul
Copy link
Contributor

flomebul commented Feb 7, 2021

Compiler version

scala version 3.0.0-M3

Minimized code

object Issue11341 {
  class ClsA(i: Int) extends Ordered[ClsA] {
    def compare(that: ClsA): Int = ???

    // Members declared in java.lang.Comparable
    override def compareTo(that: ClsA | UncheckedNull): Int = ???
  } 

  class ClsB(i: Int) extends Ordered[ClsB] {
    def compare(that: ClsB): Int = ???

    // Members declared in java.lang.Comparable
    override def compareTo(that: ClsB): Int = ???
  } 

  class ClsC(i: Int) extends Ordered[ClsC] {
    def compare(that: ClsC): Int = ???
  } 
}

Output

def compareTo(that: asuivre.Issue11341.ClsA | UncheckedNull): Int
error overriding method compareTo in trait Ordered of type (that: asuivre.Issue11341.ClsA): Int;
  method compareTo of type (that: asuivre.Issue11341.ClsA | UncheckedNull): Int has incompatible type

class ClsB: asuivre.Issue11341.ClsB
class ClsB needs to be abstract, since def compareTo(x$0: T | UncheckedNull): Int is not defined 
(Note that T | UncheckedNull does not match asuivre.Issue11341.ClsB)

def compareTo(that: asuivre.Issue11341.ClsB): Int
error overriding method compareTo in trait Comparable of type (x$0: asuivre.Issue11341.ClsB | UncheckedNull): Int;
  method compareTo of type (that: asuivre.Issue11341.ClsB): Int has incompatible type

class ClsC: asuivre.Issue11341.ClsC
class ClsC needs to be abstract, since def compareTo(x$0: T | UncheckedNull): Int is not defined 
(Note that T | UncheckedNull does not match asuivre.Issue11341.ClsC)

Expectation

I suppose that the case "ClsC" is the right one, as it is the case without the "-Yexplicit-nulls" flag.

@noti0na1
Copy link
Member

noti0na1 commented Feb 8, 2021

I tested this example using the new explicit nulls PR #9884 (We no longer have UncheckedNull, so it need to be repleced by Null).

The output is:

    |  override def compareTo(that: ClsA | Null): Int = ???
    |               ^
    |error overriding method compareTo in trait Ordered of type (that: ClsA): Int;
    |  method compareTo of type (that: ClsA | Null): Int has incompatible type

I think this is expected in the current design. In the PR, we have a relaxed overriding rule when the overrided member is defined in Java.

However in this case, Ordered is a scala trait, and it overrides the compareTo function. Therefore, compareTo becomes a scala function and the special rule doesn't apply. The only way to override compareTo here is override def compareTo(that: ClsA): Int.

In theory, we may compare an object to a null pointer, but the current standard lib is not compiled using explicit nulls, we are unable to add | Null to the param type.

A workaround is to cast that: ClsA to ClsA | Null and then compare it to null.

@olhotak
Copy link
Contributor

olhotak commented Feb 8, 2021

Do ClsB and ClsC compile with #9884?

I think that is the desired behaviour in this case, that ClsB and ClsC compile but ClsA doesn't.

@noti0na1
Copy link
Member

noti0na1 commented Feb 8, 2021

@olhotak Yes, ClsB and ClsC can be compiled successfully.

@flomebul
Copy link
Contributor Author

flomebul commented Feb 8, 2021

If ClsC compile, it is exactly what is expected. Thanks

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

4 participants