diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index c5fcfadba2c2..41fbd888b641 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -475,7 +475,10 @@ object CheckUnused: && !imp.isGeneratedByEnum && !ctx.owner.name.isReplWrapperName then - imps.put(imp, ()) + if imp.isCompiletimeTesting then + isNullified = true + else + imps.put(imp, ()) case tree: Bind => if !tree.name.isInstanceOf[DerivedName] && !tree.name.is(WildcardParamName) then if tree.hasAttachment(NoWarn) then @@ -505,6 +508,9 @@ object CheckUnused: asss.addOne(sym) else refs.addOne(sym) + + // currently compiletime.testing is completely erased, so ignore the unit + var isNullified = false end RefInfos // Names are resolved by definitions and imports, which have four precedence levels: @@ -519,7 +525,7 @@ object CheckUnused: inline def weakerThan(q: Precedence): Boolean = p > q inline def isNone: Boolean = p == NoPrecedence - def reportUnused()(using Context): Unit = + def reportUnused()(using Context): Unit = if !refInfos.isNullified then for (msg, pos, origin) <- warnings do if origin.isEmpty then report.warning(msg, pos) else report.warning(msg, pos, origin) @@ -1003,6 +1009,10 @@ object CheckUnused: def isGeneratedByEnum: Boolean = imp.symbol.exists && imp.symbol.owner.is(Enum, butNot = Case) + /** No mechanism for detection yet. */ + def isCompiletimeTesting: Boolean = + imp.expr.symbol == defn.CompiletimeTestingPackage//.moduleClass + extension (pos: SrcPos) def isZeroExtentSynthetic: Boolean = pos.span.isSynthetic && pos.span.isZeroExtent def isSynthetic: Boolean = pos.span.isSynthetic && pos.span.exists diff --git a/tests/warn/i21805.scala b/tests/warn/i21805.scala new file mode 100644 index 000000000000..9d991d35efc8 --- /dev/null +++ b/tests/warn/i21805.scala @@ -0,0 +1,31 @@ +//> using options -Wunused:all + +def i23967: Boolean = { + //import scala.compiletime.testing.typeCheckErrors + import scala.compiletime.testing.* // nowarn + typeChecks("2 + 2") +} + +package p: + val code = """"hello, world"""" +package c: + class C(i: Int) + +package q: + import c.* // nowarn, unit is nullified + import p.* // nowarn + import scala.compiletime.testing.* + def test() = typeCheckErrors("""println(C("hello, world"))""") + def ok() = typeChecks("println(code)") + inline def f(inline i: Int) = 42 + i + +package i23967b: + package ok: + import scala.compiletime.testing.* // nowarn + def test() = typeChecks("42 + 27") + package nok: + import scala.compiletime.testing.typeChecks // nowarn + def test() = typeChecks("42 + 27") + +@main def Test = println: + q.f(27)