diff --git a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala index 7be02b6b19ec..21515695f2e6 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckUnused.scala @@ -55,7 +55,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha if tree.symbol.exists then // if in an inline expansion, resolve at summonInline (synthetic pos) or in an enclosing call site val resolving = - tree.srcPos.isUserCode + tree.srcPos.isUserCode(using if tree.hasAttachment(InlinedParameter) then ctx.outer else ctx) || tree.srcPos.isZeroExtentSynthetic // take as summonInline if !ignoreTree(tree) then def loopOverPrefixes(prefix: Type, depth: Int): Unit = @@ -140,6 +140,10 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha case _ => tree + override def prepareForInlined(tree: Inlined)(using Context): Context = + if tree.inlinedFromOuterScope then + tree.expansion.putAttachment(InlinedParameter, ()) + ctx override def transformInlined(tree: Inlined)(using Context): tree.type = if !tree.call.isEmpty then if !refInfos.calls.containsKey(tree.call) then @@ -422,6 +426,9 @@ object CheckUnused: /** Tree is LHS of Assign. */ val AssignmentTarget = Property.StickyKey[Unit] + /** Tree is an inlined parameter. */ + val InlinedParameter = Property.StickyKey[Unit] + class PostTyper extends CheckUnused(PhaseMode.Aggregate, "PostTyper") class PostInlining extends CheckUnused(PhaseMode.Report, "PostInlining") @@ -1010,7 +1017,7 @@ object CheckUnused: def isUserCode(using Context): Boolean = val inlineds = enclosingInlineds // per current context inlineds.isEmpty - || inlineds.last.srcPos.sourcePos.contains(pos.sourcePos) + || inlineds.exists(_.srcPos.sourcePos.contains(pos.sourcePos)) // include intermediate inlinings or quotes extension [A <: AnyRef](arr: Array[A]) // returns `until` if not satisfied diff --git a/tests/warn/i24248/lib.scala b/tests/warn/i24248/lib.scala new file mode 100644 index 000000000000..8244d509f8f4 --- /dev/null +++ b/tests/warn/i24248/lib.scala @@ -0,0 +1,18 @@ + +import scala.quoted.* + +trait Thing +object Stuff: + given Thing() + +object lib: + inline def m: Thing = ${ mImpl[Thing] } + + def mImpl[T](using Quotes, Type[T]): Expr[T] = + import quotes.reflect.* + val thing = Implicits.search(TypeRepr.of[T]) match + case iss: ImplicitSearchSuccess => iss.tree.asExprOf[T] + '{ + val res = $thing + res + } diff --git a/tests/warn/i24248/test.scala b/tests/warn/i24248/test.scala new file mode 100644 index 000000000000..35137a5646c9 --- /dev/null +++ b/tests/warn/i24248/test.scala @@ -0,0 +1,6 @@ +//> using options -Werror -Wunused:all + +import Stuff.given + +@main def test = println: + lib.m