Skip to content

Commit a791e52

Browse files
committed
Only capture contextual implicits
1 parent c723851 commit a791e52

File tree

2 files changed

+35
-23
lines changed

2 files changed

+35
-23
lines changed

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,19 +1103,24 @@ trait Implicits { self: Typer =>
11031103
val eligible =
11041104
if (contextual) ctx.implicits.eligible(wildProto)
11051105
else implicitScope(wildProto).eligible
1106-
searchImplicits(eligible, contextual).recoverWith {
1107-
failure => failure.reason match {
1108-
case _: AmbiguousImplicits => failure
1109-
case reason =>
1110-
if (contextual)
1111-
bestImplicit(contextual = false).recoverWith {
1112-
failure2 => reason match {
1113-
case (_: DivergingImplicit) | (_: ShadowedImplicit) => failure
1114-
case _ => failure2
1106+
searchImplicits(eligible, contextual) match {
1107+
case result: SearchSuccess =>
1108+
if (contextual && ctx.mode.is(Mode.BodyOfInlined))
1109+
Inliner.markContextualImplicit(result.tree)
1110+
result
1111+
case failure: SearchFailure =>
1112+
failure.reason match {
1113+
case _: AmbiguousImplicits => failure
1114+
case reason =>
1115+
if (contextual)
1116+
bestImplicit(contextual = false).recoverWith {
1117+
failure2 => reason match {
1118+
case (_: DivergingImplicit) | (_: ShadowedImplicit) => failure
1119+
case _ => failure2
1120+
}
11151121
}
1116-
}
1117-
else failure
1118-
}
1122+
else failure
1123+
}
11191124
}
11201125
}
11211126

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,15 @@ import util.Property
3232
object Inliner {
3333
import tpd._
3434

35+
/** Marks an implicit reference found in the context (as opposed to the implicit scope)
36+
* from an inlineable body. Such references will be carried along with the body to
37+
* the expansion site.
38+
*/
39+
private val ContextualImplicit = new Property.StickyKey[Unit]
40+
41+
def markContextualImplicit(tree: Tree)(implicit ctx: Context): Unit =
42+
methPart(tree).putAttachment(ContextualImplicit, ())
43+
3544
class InlineAccessors extends AccessProxies {
3645

3746
/** A tree map which inserts accessors for all non-public term members accessed
@@ -144,10 +153,11 @@ object Inliner {
144153
val nameAtPos = mutable.Map[Position, Name]()
145154
val implicitSyms = mutable.Set[Symbol]()
146155
val implicitRefs = new mutable.ListBuffer[Tree]
147-
def registerIfImplicit(tree: Tree) = tree match {
156+
def registerIfContextualImplicit(tree: Tree) = tree match {
148157
case tree: RefTree
149-
if tree.pos.start == tree.pos.end && tree.symbol.is(Implicit) &&
150-
isExternal(tree.symbol) && !implicitSyms.contains(tree.symbol) =>
158+
if tree.removeAttachment(ContextualImplicit).isDefined &&
159+
isExternal(tree.symbol) &&
160+
!implicitSyms.contains(tree.symbol) =>
151161
if (tree.existsSubTree(t => isLocal(tree.symbol, inlineMethod)))
152162
ctx.warning("implicit reference $tree is dropped at inline site because it refers to local symbol(s)", tree.pos)
153163
else {
@@ -169,7 +179,7 @@ object Inliner {
169179
nameAtPos(tree.pos.toSynthetic) = tree.symbol.name
170180
case _ =>
171181
}
172-
registerIfImplicit(tree)
182+
registerIfContextualImplicit(tree)
173183
traverseChildren(tree)
174184
}
175185
}
@@ -521,21 +531,18 @@ class Inliner(call: tpd.Tree, rhsToInline: tpd.Tree)(implicit ctx: Context) {
521531

522532
trace(i"inlining $call\n, BINDINGS =\n${bindingsBuf.toList}%\n%\nEXPANSION =\n$expansion", inlining, show = true) {
523533

524-
//println(i"body = $rhsToInline")
525-
//println(i"expansion = $expansion")
534+
// println(i"body = $rhsToInline")
526535

527536
// The final expansion runs a typing pass over the inlined tree. See InlineTyper for details.
528537
val expansion1 = inlineTyper.typed(expansion, pt)(inlineCtx)
529538

530-
//println(i"typed expansion = $expansion1")
531-
532539
/** All bindings in `bindingsBuf` except bindings of inlineable closures */
533540
val bindings = bindingsBuf.toList.map(_.withPos(call.pos))
534541

535-
val (finalBindings, finalExpansion) = dropUnusedDefs(bindings, expansion1)
542+
inlining.println(i"original bindings = $bindings%\n%")
543+
inlining.println(i"original expansion = $expansion1")
536544

537-
//println(i"bindings buf = ${bindingsBuf.toList}%; %")
538-
//println(i"bindings = ${bindings.toList}%; %")
545+
val (finalBindings, finalExpansion) = dropUnusedDefs(bindings, expansion1)
539546

540547
tpd.Inlined(call, finalBindings, finalExpansion)
541548
}

0 commit comments

Comments
 (0)