Skip to content

Commit 2f320b8

Browse files
authored
Use enclosing enclosingInlineds for empty call (#24281)
Fixes #24248 Adjust enclosing inlineds for inlined parameter, and do look-up in imports if tree position is enclosed by any enclosing inlined position (any intermediate position, not just outermost).
1 parent 11ecbfb commit 2f320b8

File tree

3 files changed

+33
-2
lines changed

3 files changed

+33
-2
lines changed

compiler/src/dotty/tools/dotc/transform/CheckUnused.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
5555
if tree.symbol.exists then
5656
// if in an inline expansion, resolve at summonInline (synthetic pos) or in an enclosing call site
5757
val resolving =
58-
tree.srcPos.isUserCode
58+
tree.srcPos.isUserCode(using if tree.hasAttachment(InlinedParameter) then ctx.outer else ctx)
5959
|| tree.srcPos.isZeroExtentSynthetic // take as summonInline
6060
if !ignoreTree(tree) then
6161
def loopOverPrefixes(prefix: Type, depth: Int): Unit =
@@ -156,6 +156,10 @@ class CheckUnused private (phaseMode: PhaseMode, suffix: String) extends MiniPha
156156
case _ =>
157157
tree
158158

159+
override def prepareForInlined(tree: Inlined)(using Context): Context =
160+
if tree.inlinedFromOuterScope then
161+
tree.expansion.putAttachment(InlinedParameter, ())
162+
ctx
159163
override def transformInlined(tree: Inlined)(using Context): tree.type =
160164
transformAllDeep(tree.call)
161165
tree
@@ -495,6 +499,9 @@ object CheckUnused:
495499
/** Tree is LHS of Assign. */
496500
val AssignmentTarget = Property.StickyKey[Unit]
497501

502+
/** Tree is an inlined parameter. */
503+
val InlinedParameter = Property.StickyKey[Unit]
504+
498505
class PostTyper extends CheckUnused(PhaseMode.Aggregate, "PostTyper")
499506

500507
class PostInlining extends CheckUnused(PhaseMode.Report, "PostInlining")
@@ -1063,7 +1070,7 @@ object CheckUnused:
10631070
def isUserCode(using Context): Boolean =
10641071
val inlineds = enclosingInlineds // per current context
10651072
inlineds.isEmpty
1066-
|| inlineds.last.srcPos.sourcePos.contains(pos.sourcePos)
1073+
|| inlineds.exists(_.srcPos.sourcePos.contains(pos.sourcePos)) // include intermediate inlinings or quotes
10671074

10681075
extension [A <: AnyRef](arr: Array[A])
10691076
// returns `until` if not satisfied

tests/warn/i24248/lib.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
import scala.quoted.*
3+
4+
trait Thing
5+
object Stuff:
6+
given Thing()
7+
8+
object lib:
9+
inline def m: Thing = ${ mImpl[Thing] }
10+
11+
def mImpl[T](using Quotes, Type[T]): Expr[T] =
12+
import quotes.reflect.*
13+
val thing = Implicits.search(TypeRepr.of[T]) match
14+
case iss: ImplicitSearchSuccess => iss.tree.asExprOf[T]
15+
'{
16+
val res = $thing
17+
res
18+
}

tests/warn/i24248/test.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//> using options -Werror -Wunused:all
2+
3+
import Stuff.given
4+
5+
@main def test = println:
6+
lib.m

0 commit comments

Comments
 (0)