Skip to content

Commit c683f1c

Browse files
committed
wip for implicits handling root imports.
1 parent d4f3dfe commit c683f1c

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed

src/dotty/tools/dotc/core/Contexts.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,10 @@ object Contexts {
164164
else if (isImportContext) importInfo.importedImplicits
165165
else if (isNonEmptyScopeContext) scope.implicitDecls
166166
else Nil
167-
if (implicitRefs.isEmpty) outer.implicits
168-
else new ContextualImplicits(implicitRefs, outer.implicits.ctx)(this)
167+
if (implicitRefs.isEmpty && !(isImportContext && importInfo.isRootImport))
168+
outer.implicits // record root imports because they hide implicits in same import further out
169+
else
170+
new ContextualImplicits(implicitRefs, outer.implicits)(this)
169171
}
170172
implicitsCache
171173
}
@@ -346,7 +348,7 @@ object Contexts {
346348

347349
object NoContext extends Context {
348350
lazy val base = unsupported("base")
349-
override def implicits: ContextualImplicits = new ContextualImplicits(Nil, this)(this)
351+
override val implicits: ContextualImplicits = new ContextualImplicits(Nil, null)(this)
350352
}
351353

352354
/** A context base defines state and associated methods that exist once per

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ object Implicits {
131131
* name, b, whereas the name of the symbol is the original name, a.
132132
* @param outerCtx the next outer context that makes visible further implicits
133133
*/
134-
class ContextualImplicits(val refs: List[TermRef], val outerCtx: Context)(initctx: Context) extends ImplicitRefs(initctx) {
134+
class ContextualImplicits(val refs: List[TermRef], val outerImplicits: ContextualImplicits)(initctx: Context) extends ImplicitRefs(initctx) {
135135
private val eligibleCache = new mutable.AnyRefMap[Type, List[TermRef]]
136136

137137
/** The implicit references that are eligible for type `tp`. */
@@ -141,8 +141,8 @@ object Implicits {
141141
case Some(eligibles) =>
142142
def elided(ci: ContextualImplicits): Int = {
143143
val n = ci.refs.length
144-
if (ci.outerCtx == NoContext) n
145-
else n + elided(ci.outerCtx.implicits)
144+
if (ci.outerImplicits == null) n
145+
else n + elided(ci.outerImplicits)
146146
}
147147
if (monitored) record(s"elided eligible refs", elided(this))
148148
eligibles
@@ -156,16 +156,16 @@ object Implicits {
156156
private def computeEligible(tp: Type): List[TermRef] = /*>|>*/ ctx.traceIndented(i"computeEligible $tp in $refs%, %", implicitsDetailed) /*<|<*/ {
157157
if (monitored) record(s"check eligible refs in ctx", refs.length)
158158
val ownEligible = filterMatching(tp)
159-
if (outerCtx == NoContext) ownEligible
159+
if (outerImplicits == null) ownEligible
160160
else ownEligible ::: {
161161
val shadowed = (ownEligible map (_.name)).toSet
162-
outerCtx.implicits.eligible(tp) filterNot (ref => shadowed contains ref.name)
162+
outerImplicits.eligible(tp) filterNot (ref => shadowed contains ref.name)
163163
}
164164
}
165165

166166
override def toString = {
167167
val own = s"(implicits: ${refs mkString ","})"
168-
if (outerCtx == NoContext) own else own + "\n " + outerCtx.implicits
168+
if (outerImplicits == null) own else own + "\n " + outerImplicits
169169
}
170170
}
171171

0 commit comments

Comments
 (0)