From 20c0a6a92dc2d618fa557bb19d78d8595ca527e6 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 2 Feb 2014 17:09:33 +0100 Subject: Avoid accessing implicits that come from root imports that are hidden by some nested import. This also changes the criterion when a root import is disabled. A root import is now disabled if there is an inner import from the same package or module, and the inner import contains at least one disabling clause X => _. (The latter crierion is new; without it, we would consider something like import scala.{collections => c} as a hiding import for Scala, which seems to go too far.) --- src/dotty/tools/dotc/typer/Implicits.scala | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'src/dotty/tools/dotc/typer/Implicits.scala') diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index 574db1a3d..2bd1731da 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -141,7 +141,7 @@ object Implicits { case Some(eligibles) => def elided(ci: ContextualImplicits): Int = { val n = ci.refs.length - if (ci.outerImplicits == null) n + if (ci.outerImplicits == NoContext.implicits) n else n + elided(ci.outerImplicits) } if (monitored) record(s"elided eligible refs", elided(this)) @@ -156,7 +156,7 @@ object Implicits { private def computeEligible(tp: Type): List[TermRef] = /*>|>*/ ctx.traceIndented(i"computeEligible $tp in $refs%, %", implicitsDetailed) /*<|<*/ { if (monitored) record(s"check eligible refs in ctx", refs.length) val ownEligible = filterMatching(tp) - if (outerImplicits == null) ownEligible + if (outerImplicits == NoContext.implicits) ownEligible else ownEligible ::: { val shadowed = (ownEligible map (_.name)).toSet outerImplicits.eligible(tp) filterNot (ref => shadowed contains ref.name) @@ -165,8 +165,20 @@ object Implicits { override def toString = { val own = s"(implicits: ${refs mkString ","})" - if (outerImplicits == null) own else own + "\n " + outerImplicits + if (outerImplicits == NoContext.implicits) own else own + "\n " + outerImplicits } + + /** This context, or a copy, ensuring root import from symbol `root` + * is not present in outer implicits. + */ + def exclude(root: Symbol): ContextualImplicits = + if (this == NoContext.implicits) this + else { + val outerExcluded = outerImplicits exclude root + if (ctx.importInfo.site.termSymbol == root) outerExcluded + else if (outerExcluded eq outerImplicits) this + else new ContextualImplicits(refs, outerExcluded)(ctx) + } } /** The result of an implicit search */ -- cgit v1.2.3