Skip to content

repl: Handle user-defined res definitions #13600

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

Merged
merged 1 commit into from
Sep 27, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions compiler/src/dotty/tools/repl/ReplCompiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ class ReplCompiler extends Compiler {
var valIdx = state.valIndex
val defs = new mutable.ListBuffer[Tree]

/** If the user inputs a definition whose name is of the form REPL_RES_PREFIX and a number,
* such as `val res9 = 1`, we bump `valIdx` to avoid name clashes. lampepfl/dotty#3536 */
def maybeBumpValIdx(tree: Tree): Unit = tree match
case apply: Apply => for a <- apply.args do maybeBumpValIdx(a)
case tuple: Tuple => for t <- tuple.trees do maybeBumpValIdx(t)
case patDef: PatDef => for p <- patDef.pats do maybeBumpValIdx(p)
case tree: NameTree => tree.name.show.stripPrefix(str.REPL_RES_PREFIX).toIntOption match
case Some(n) if n >= valIdx => valIdx = n + 1
case _ =>
case _ =>

flattened.foreach {
case expr @ Assign(id: Ident, _) =>
// special case simple reassignment (e.g. x = 3)
Expand All @@ -101,6 +112,7 @@ class ReplCompiler extends Compiler {
val vd = ValDef(resName, TypeTree(), expr).withSpan(expr.span)
defs += vd
case other =>
maybeBumpValIdx(other)
defs += other
}

Expand Down
19 changes: 19 additions & 0 deletions compiler/test-resources/repl/i3536
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
scala> val res0 = 1
val res0: Int = 1

scala> res0
val res1: Int = 1


scala> val res99 = 9
val res99: Int = 9

scala> res99
val res100: Int = 9


scala> val res50 = 5
val res50: Int = 5

scala> res50
val res101: Int = 5
4 changes: 4 additions & 0 deletions compiler/test-resources/repl/i3536_bind
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scala> val res10 @ Some(_) = Option(1)
val res10: Some[Int] = Some(1)
scala> res10
val res11: Some[Int] = Some(1)
4 changes: 4 additions & 0 deletions compiler/test-resources/repl/i3536_defdef
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scala> def res20 = 1
def res20: Int
scala> res20
val res21: Int = 1
4 changes: 4 additions & 0 deletions compiler/test-resources/repl/i3536_object
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scala> object res30 { override def toString = "res30" }
// defined object res30
scala> res30
val res31: res30.type = res30
5 changes: 5 additions & 0 deletions compiler/test-resources/repl/i3536_patterndef_some
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
scala> val Some((res40, res41)) = Option((1, 0))
val res40: Int = 1
val res41: Int = 0
scala> res40
val res42: Int = 1
5 changes: 5 additions & 0 deletions compiler/test-resources/repl/i3536_patterndef_tuple
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
scala> val (res40, res41) = (1, 0)
val res40: Int = 1
val res41: Int = 0
scala> res40
val res42: Int = 1
4 changes: 4 additions & 0 deletions compiler/test-resources/repl/i3536_typedef
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scala> type res50 = Int
// defined alias type res50 = Int
scala> 1
val res51: Int = 1
4 changes: 4 additions & 0 deletions compiler/test-resources/repl/i3536_var
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
scala> var res60 = 1
var res60: Int = 1
scala> res60
val res61: Int = 1