Skip to content
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

Infer result type using type of overridden method, if any (and not using the rhs) #7212

Closed
scabug opened this issue Mar 4, 2013 · 16 comments · Fixed by scala/scala#9891
Closed
Assignees
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) has PR infer
Milestone

Comments

@scabug
Copy link

scabug commented Mar 4, 2013

An old email for which I never opened a ticket. It is undesirable that implementing an abstract method with an implementation like sys.error("no implementation yet") should force all subclasses to throw an exception. It is extremely unlikely anyone would want this "most specific type" to be inferred as the return type of a method for which less exceptional return type is already known (i.e. I'm not talking about def ??? which is born in the same location as the exception; I'm talking about any method for which there is an abstract or concrete implementation in a superclass.)

In the following, how does one define foo in class B such that:

 1) class A's foo definitions can be swapped without modifying B
 2) class C compiles

Can you? I can't.  But I should be able to.

  class A {
    def foo = new A
    // def foo = new B
  }

  class B extends A {
    override def foo = sys.error("")
  }

  class C extends B {
    override def foo = new C
  }
@scabug
Copy link
Author

scabug commented Mar 4, 2013

Imported From: https://issues.scala-lang.org/browse/SI-7212?orig=1
Reporter: @paulp
See #7873

@scabug
Copy link
Author

scabug commented Aug 20, 2013

@adriaanm said:

Paul Phillips
to scala-internals

It's interesting that you have some choices when looking for an unhelpful type to be inferred. Never let it be said the compiler is autocratic. You can have any color you want, as long as it's black or ebony.

trait A { def f: List[String] }
trait B extends A { def f = Nil }            // infers Nil.type
trait C extends A { def f = List() }         // infers List[Nothing]
trait D extends A { def f = List[String]() } // thanks for the type inference

// Why you might care
trait B1 extends B { override def f = List("a") }
trait C1 extends C { override def f = List("a") }
// ./a.scala:6: error: type mismatch;
//  found   : List[String]
//  required: scala.collection.immutable.Nil.type
// trait B1 extends B { override def f = List("a") }
//                                           ^
// ./a.scala:7: error: type mismatch;
//  found   : String("a")
//  required: Nothing
// trait C1 extends C { override def f = List("a") }
//                                            ^

@scabug
Copy link
Author

scabug commented Aug 20, 2013

@adriaanm said:
This likely makes incremental compilation juuuust a little bit harder still.

@scabug
Copy link
Author

scabug commented Jan 28, 2014

@adriaanm said:
Wish I had gotten around to do this -- will have to wait until 2.12, but thinking of enabling it under -future in 2.11.1.

@scabug
Copy link
Author

scabug commented Mar 13, 2014

@adriaanm said:
Design discussions get a wider audience on scala-internals, so I recommend discussing there. The inherited return type seems more appropriate to me

@scabug
Copy link
Author

scabug commented May 30, 2016

@adriaanm said:
I've made a bit of progress on this while reworking our fields encoding, but this will have to go in under a flag first during 2.12.x.

@scabug
Copy link
Author

scabug commented Jun 13, 2016

@som-snytt said:
I just did that thing where you stare at two identical pieces of test code, identical except that one issues "inferred existential type" at the first line.

      val ref = new SimpleSpec with Reference with Property {
        type ThisCommandLine = SpecCommandLine
        protected def creator(args: List[String]): ThisCommandLine = new SpecCommandLine(args) 
        //def referenceSpec: Reference = this    // perniciously, the type is required
        def referenceSpec = this                 // not even used, could be ??? here
        override def propMapper = new PropertyMapper(this)
      }

@adriaanm
Copy link
Contributor

This could also be interesting to speed up compilation by using the inherited type rather than type checking the RHS. The decision point is in assignTypeToTree.

Too late for 2.13, though.

@adriaanm adriaanm modified the milestones: 2.13.0-RC1, 2.14.0-M1 Nov 13, 2018
@smarter smarter added the fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) label Nov 13, 2018
@Jasper-M
Copy link
Member

Jasper-M commented Feb 14, 2019

I'm not sure if I should prefer the behavior of dotty...
If you're defining public API, especially non-final, you should give it an explicit return type.

@SethTisue
Copy link
Member

I've opened a ticket suggesting the Scala 3 migration guide mention this: scalacenter/scala-3-migration-guide#181

@SethTisue
Copy link
Member

closing as out of scope for Scala 2

@som-snytt
Copy link

Worst possible resolution. Did I ever PR this? This is so obvious etc.

@SethTisue
Copy link
Member

perhaps someone would like to PR it under -Xsource:3?

@som-snytt
Copy link

My duplicate ticket from 2013 was #8159 in case that inspires someone. I thought this already had a PR by lrytz or adriaanm.

@som-snytt
Copy link

I came across this again because test https://github.com/scala/scala/blob/2.13.x/test/files/neg/t2441.scala for #2441 is fixed in Scala 3 under this change. I had forgotten I'd just been here during pandemic.

@SethTisue
Copy link
Member

linked PR changes the behavior, but only under -Xsource:3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) has PR infer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants