False positive unused import involving type alias and extractor
Closed this issue · 3 comments
SethTisue commented
Compiler version
3.6.4 (and also the current 3.7 nightly)
Minimized code
//> using scala 3.nightly
//> using option -Wunused:imports
object tpd:
type Block = Trees.Block
object Trees:
case class Block(x: Int)
trait Bug:
import tpd.Block
def foo: Unit =
(??? : Any) match
case Block(_) =>Output
[warn] ./S.scala:11:14
[warn] unused import
[warn] import tpd.Block
[warn] ^^^^^
Expectation
The import is used. The code does not compile without it. The type alias must be confusing the compiler.
som-snytt commented
The tree is
CaseDef(
Typed(
UnApply(Select(Ident(Block), unapply), List(), List(Ident(_))),
TypeTree()),
for
case Trees.Block(_):Trees.Block =>
som-snytt commented
This compiles only by importing the alias:
object tpd:
type Block = Trees.Block
object Trees:
abstract case class Block(x: Int)
private object Block
val block = new Block(42) {}
@main def test = println:
import tpd.Block
//import Trees.Block
(Trees.block: Any) match
case Block(_) =>
That is clearly wrong.
Normally, the reference to Block, resolved by an import, becomes prefix.Block; but in the example, typechecking the pattern has snuck in the term reference.
The Block in the UnApply is indeed the private companion Trees.Block:
ID(Block) or TermRef(ThisType(TypeRef(ThisType(TypeRef(NoPrefix,module class <empty>)),module class Trees$)),object Block) at tests/warn/i22787.scala:<293..293>
som-snytt commented
Apparently, my previous comment intended to ask, What is a constructor pattern? If it compiles to unapply, is access to the companion module required? Probably, the question is moot because it is about the internal compiler fiction.