Skip to content

case class with NoStackTrace won't compile with #13608

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
bblfish opened this issue Sep 24, 2021 · 3 comments · Fixed by #13647
Closed

case class with NoStackTrace won't compile with #13608

bblfish opened this issue Sep 24, 2021 · 3 comments · Fixed by #13647

Comments

@bblfish
Copy link

bblfish commented Sep 24, 2021

Compiler version

3.0.2
3.1.0-RC2
running on Java 17

Minimized code

I get this error when running the command line with 3.0.2 but also when compiling my project
in SBT with 3.1.0-RC2.

$ scala -version                                                                           127 
Scala compiler version 3.0.2 -- Copyright 2002-2021, LAMP/EPFL
$ scala -Yexplicit-nulls                                                                   127 
scala> import scala.util.control.NoStackTrace

scala> case class ParseException(line: Int, character: Int, message: String) extends NoStackTrace
-- Error:
1 |case class ParseException(line: Int, character: Int, message: String) extends NoStackTrace
  |           ^
  |class ParseException cannot be defined due to a conflict between its parents when
  |implementing a super-accessor for fillInStackTrace in trait NoStackTrace:
  |
  |1. One of its parent (NoStackTrace) contains a call super.fillInStackTrace in its body,
  |   and when a super-call in a trait is written without an explicit parent
  |   listed in brackets, it is implemented by a generated super-accessor in
  |   the class that extends this trait based on the linearization order of
  |   the class.
  |2. Because Throwable comes before NoStackTrace in the linearization
  |   order of ParseException, and because Throwable overrides fillInStackTrace,
  |   the super-accessor in ParseException is implemented as a call to
  |   super[Throwable].fillInStackTrace.
  |3. However,
  |   (): Throwable | Null (the type of super[Throwable].fillInStackTrace in ParseException)
  |   is not a subtype of
  |   (): Throwable (the type of fillInStackTrace in trait NoStackTrace).
  |   Hence, the super-accessor that needs to be generated in ParseException
  |   is illegal.
  |
  |Here are two possible ways to resolve this:
  |
  |1. Change the linearization order of ParseException such that
  |   NoStackTrace comes before Throwable.
  |2. Alternatively, replace super.fillInStackTrace in the body of trait NoStackTrace by a
  |   super-call to a specific parent, e.g. super[Throwable].fillInStackTrace

Output

// TODO add output here

Expectation

@bblfish
Copy link
Author

bblfish commented Sep 24, 2021

Workaround by passing "writeableStackTrace=false"

case class ParseException(line: Int, character: Int, messageStr: String)
	extends Throwable(messageStr,null,  true,  false)

@odersky
Copy link
Contributor

odersky commented Sep 24, 2021

Nice puzzler! @noti0na1 do you want to take a look?

@noti0na1
Copy link
Member

noti0na1 commented Sep 24, 2021

Sure. It looks like a issue related to overriding?

The overriding in explicit nulls is still broken, I'm working it recently.

@noti0na1 noti0na1 linked a pull request Oct 1, 2021 that will close this issue
@Kordyjan Kordyjan added this to the 3.1.1 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants