aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Implicits.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-10-15 14:55:00 +0200
committerMartin Odersky <odersky@gmail.com>2013-10-15 14:55:09 +0200
commit4f05aa9bf0d3c29eae720115433ffe29b239d70f (patch)
treedbc9c8a430351c0a5b372adc9442c1b74ff92d54 /src/dotty/tools/dotc/typer/Implicits.scala
parentcdafc3058566d5eede8995f0812fe57a3a1ad6ee (diff)
downloaddotty-4f05aa9bf0d3c29eae720115433ffe29b239d70f.tar.gz
dotty-4f05aa9bf0d3c29eae720115433ffe29b239d70f.tar.bz2
dotty-4f05aa9bf0d3c29eae720115433ffe29b239d70f.zip
Changes to adaptation and local type inference.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Implicits.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala31
1 files changed, 16 insertions, 15 deletions
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 832693b98..05db467f0 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -27,6 +27,9 @@ import collection.mutable
/** Implicit resolution */
object Implicits {
+ private def disableImplicits(ctx: Context): Context =
+ if (ctx == NoContext) ctx else ctx retractMode Mode.ImplicitsEnabled
+
/** A common base class of contextual implicits and of-type implicits which
* represents as set of implicit references.
*/
@@ -61,7 +64,7 @@ object Implicits {
class OfTypeImplicits(tp: Type, val companionRefs: TermRefSet)(initctx: Context)
extends ImplicitRefs {
assert(initctx.typer != null)
- implicit val ctx: Context = initctx retractMode ImplicitsEnabled
+ implicit val ctx: Context = disableImplicits(initctx)
val refs: List[TermRef] = companionRefs.toList flatMap (_.implicitMembers)
/** The implicit references that are eligible for expected type `tp` */
@@ -76,8 +79,7 @@ object Implicits {
* @param outerCtx the next outer context that makes visible further implicits
*/
class ContextualImplicits(val refs: List[TermRef], val outerCtx: Context)(initctx: Context) extends ImplicitRefs {
- implicit val ctx: Context =
- if (initctx == NoContext) initctx else initctx retractMode Mode.ImplicitsEnabled
+ implicit val ctx: Context = disableImplicits(initctx)
private val eligibleCache = new mutable.HashMap[Type, List[TermRef]]
@@ -259,7 +261,7 @@ trait Implicits { self: Typer =>
* @param pos The position where errors should be reported.
*/
def inferImplicit(pt: Type, argument: Tree, pos: Position)(implicit ctx: Context): SearchResult = track("inferImplicit") {
- ctx.traceIndented(s"search implicit ${pt.show}, arg = ${argument.show}", show = true) {
+ ctx.traceIndented(s"search implicit ${pt.show}, arg = ${argument.show}: ${argument.tpe.show}", show = true) {
val isearch =
if (ctx.settings.explaintypes.value) new ExplainedImplicitSearch(pt, argument, pos)
else new ImplicitSearch(pt, argument, pos)
@@ -275,7 +277,7 @@ trait Implicits { self: Typer =>
/** An implicit search; parameters as in `inferImplicit` */
class ImplicitSearch(protected val pt: Type, protected val argument: Tree, pos: Position)(implicit ctx: Context) {
- val initctx: Context = ctx.fresh.withNewTyperState.retractMode(ImplicitsEnabled)
+ val initctx: Context = disableImplicits(ctx.fresh.withNewTyperState)
def nestedContext = initctx.fresh.withNewTyperState
protected def nonMatchingImplicit(ref: TermRef): SearchFailure = NoImplicitMatches
@@ -287,19 +289,18 @@ trait Implicits { self: Typer =>
def searchImplicits(eligible: List[TermRef], contextual: Boolean): SearchResult = {
/** Try to typecheck an implicit reference */
- def typedImplicit(ref: TermRef)(implicit ctx: Context): SearchResult = track("typedImplicit") {
- val id = Ident(ref).withPos(pos)
- val tree =
- if (argument.isEmpty)
- adapt(id, pt)
- else
- typed(untpd.Apply(untpd.TypedSplice(id), untpd.TypedSplice(argument) :: Nil), pt)
+ def typedImplicit(ref: TermRef)(implicit ctx: Context): SearchResult = track("typedImplicit") { ctx.traceIndented(s"typed implicit $ref, pt = $pt, implicitsEnabled == ${ctx.mode is ImplicitsEnabled}", show = true) {
+ var generated: Tree = Ident(ref).withPos(pos)
+ if (!argument.isEmpty)
+ generated = typedUnadapted(
+ untpd.Apply(untpd.TypedSplice(generated), untpd.TypedSplice(argument) :: Nil), pt)
+ val generated1 = interpolateAndAdapt(generated, pt)
lazy val shadowing =
typed(untpd.Ident(ref.name), ref)(nestedContext).tpe
if (ctx.typerState.reporter.hasErrors) nonMatchingImplicit(ref)
else if (contextual && !(shadowing =:= ref)) shadowedImplicit(ref, shadowing)
- else SearchSuccess(tree)(ref, ctx.typerState)
- }
+ else SearchSuccess(generated)(ref, ctx.typerState)
+ }}
/** Given a list of implicit references, produce a list of all implicit search successes,
* where the first is supposed to be the best one.
@@ -312,7 +313,7 @@ trait Implicits { self: Typer =>
case fail: SearchFailure =>
rankImplicits(pending1, acc)
case best: SearchSuccess =>
- val newPending = pending filterNot (isAsGood(_, best.ref))
+ val newPending = pending1 filterNot (isAsGood(_, best.ref)(nestedContext.withExploreTyperState))
rankImplicits(newPending, best :: acc)
}
case nil => acc