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

Extraordinary rendition in REPL #14473

Closed
som-snytt opened this issue Feb 14, 2022 · 0 comments · Fixed by #14702
Closed

Extraordinary rendition in REPL #14473

som-snytt opened this issue Feb 14, 2022 · 0 comments · Fixed by #14702
Assignees
Milestone

Comments

@som-snytt
Copy link
Contributor

Compiler version

3.1.0, 3.1.1

Minimized code

scala> val (x,y) = if true then "" else (42,17)
scala.MatchError:  (of class java.lang.String)
  ... 30 elided
java.lang.NoClassDefFoundError: Could not initialize class repl$.rs$line$3$
  at repl$.rs$line$3.y(rs$line$3)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:568)
  at dotty.tools.repl.Rendering.$anonfun$3(Rendering.scala:116)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.Rendering.valueOf(Rendering.scala:116)
  at dotty.tools.repl.Rendering.renderVal(Rendering.scala:153)
  at dotty.tools.repl.ReplDriver.$anonfun$13(ReplDriver.scala:325)
  at scala.collection.immutable.List.flatMap(List.scala:293)
  at scala.collection.immutable.List.flatMap(List.scala:79)
  at dotty.tools.repl.ReplDriver.extractAndFormatMembers$1(ReplDriver.scala:325)
  at dotty.tools.repl.ReplDriver.renderDefinitions$$anonfun$2(ReplDriver.scala:348)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.ReplDriver.renderDefinitions(ReplDriver.scala:351)
  at dotty.tools.repl.ReplDriver.compile$$anonfun$2(ReplDriver.scala:269)
  at scala.util.Either.fold(Either.scala:189)
  at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:286)
  at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:218)

Output

java.lang.NoClassDefFoundError: Could not initialize class repl$.rs$line$3$

Same under -source future.

  dotty git:(test/current) ./bin/scala -source future
Welcome to Scala 3.1.3-RC1-bin-SNAPSHOT-git-fd97aee (17.0.2, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.

scala> val (x,y) = if true then "" else (42,17)
1 warning found
-- Warning: -------------------------------------------------------------------------------------------------------------------------------------
1 |val (x,y) = if true then "" else (42,17)
  |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |            pattern's type (Int, Int) is more specialized than the right hand side expression's type ("" : String) | (Int, Int)
  |
  |            If the narrowing is intentional, this can be communicated by adding `: @unchecked` after the expression.
scala.MatchError:  (of class java.lang.String)
  ... 33 elided
java.lang.NoClassDefFoundError: Could not initialize class rs$line$1$
  at rs$line$1.y(rs$line$1)

Expectation

More like

scala> val 1 = 2
scala.MatchError: 2 (of class java.lang.Integer)
  ... 22 elided

scala>
@som-snytt som-snytt added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 14, 2022
@dwijnand dwijnand added area:repl and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Feb 14, 2022
@griggt griggt self-assigned this Mar 4, 2022
griggt added a commit to griggt/dotty that referenced this issue Mar 16, 2022
The right hand side of value definitions in the REPL are computed in the static
initializer for the wrapper object created for that input line (e.g. rs$line$1).
If any of these definitions throws an exception, the wrapper class will fail to
initialize, and further attempts to use the class will throw NoClassDefFoundError.

In this commit, we avoid all reflective access on a wrapper class once we notice
that it failed to initialize, and mark that wrapper object as invalid in the REPL
state. We discard all input from the failed wrapper (which may have been multi-line
containing many statements and definitions); any types, terms, aliases, or imports
defined there will not override any existing with the same name, and will not be
accessible in subsequent runs.

Fixes scala#4416
Fixes scala#14473
@Kordyjan Kordyjan added this to the 3.1.3 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