Skip to content

Commit

Permalink
Fix #18383: Never consider top-level imports as unused in the repl. (
Browse files Browse the repository at this point in the history
  • Loading branch information
sjrd committed May 2, 2024
2 parents cb554eb + 509c235 commit 05354ba
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
15 changes: 9 additions & 6 deletions compiler/src/dotty/tools/dotc/transform/CheckUnused.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import dotty.tools.dotc.core.Types.{AnnotatedType, ConstantType, NoType, TermRef
import dotty.tools.dotc.core.Flags.flagsString
import dotty.tools.dotc.core.Flags
import dotty.tools.dotc.core.Names.Name
import dotty.tools.dotc.core.NameOps.isReplWrapperName
import dotty.tools.dotc.transform.MegaPhase.MiniPhase
import dotty.tools.dotc.core.Annotations
import dotty.tools.dotc.core.Definitions
Expand Down Expand Up @@ -423,9 +424,11 @@ object CheckUnused:
def registerImport(imp: tpd.Import)(using Context): Unit =
if !tpd.languageImport(imp.expr).nonEmpty && !imp.isGeneratedByEnum && !isTransparentAndInline(imp) then
impInScope.top += imp
unusedImport ++= imp.selectors.filter { s =>
!shouldSelectorBeReported(imp, s) && !isImportExclusion(s) && !isImportIgnored(imp, s)
}
if currScopeType.top != ScopeType.ReplWrapper then // #18383 Do not report top-level import's in the repl as unused
unusedImport ++= imp.selectors.filter { s =>
!shouldSelectorBeReported(imp, s) && !isImportExclusion(s) && !isImportIgnored(imp, s)
}
end registerImport

/** Register (or not) some `val` or `def` according to the context, scope and flags */
def registerDef(memDef: tpd.MemberDef)(using Context): Unit =
Expand Down Expand Up @@ -794,12 +797,13 @@ object CheckUnused:
enum ScopeType:
case Local
case Template
case ReplWrapper
case Other

object ScopeType:
/** return the scope corresponding to the enclosing scope of the given tree */
def fromTree(tree: tpd.Tree): ScopeType = tree match
case _:tpd.Template => Template
def fromTree(tree: tpd.Tree)(using Context): ScopeType = tree match
case tree: tpd.Template => if tree.symbol.name.isReplWrapperName then ReplWrapper else Template
case _:tpd.Block => Local
case _ => Other

Expand All @@ -810,4 +814,3 @@ object CheckUnused:
val Empty = UnusedResult(Set.empty)

end CheckUnused

14 changes: 14 additions & 0 deletions compiler/test-resources/repl/i18383
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
scala>:settings -Wunused:all

scala> import scala.collection.*

scala> class Foo { import scala.util.*; println("foo") }
1 warning found
-- Warning: --------------------------------------------------------------------
1 | class Foo { import scala.util.*; println("foo") }
| ^
| unused import
// defined class Foo

scala> { import scala.util.*; "foo" }
val res0: String = foo
9 changes: 8 additions & 1 deletion compiler/test/dotty/tools/repl/ReplCompilerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class ReplCompilerTests extends ReplTest:
assertEquals("def foo: 1", storedOutput().trim)
}

@Test def i18383NoWarnOnUnusedImport: Unit = {
initially {
run("import scala.collection.*")
} andThen {
println(lines().mkString("* ", "\n * ", ""))
}
}

@Test def compileTwo =
initially {
run("def foo: 1 = 1")
Expand Down Expand Up @@ -509,4 +517,3 @@ class ReplHighlightTests extends ReplTest(ReplTest.defaultOptions.filterNot(_.st
case class Tree(left: Tree, right: Tree)
def deepTree(depth: Int): Tree
deepTree(300)""")

0 comments on commit 05354ba

Please sign in to comment.