diff options
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 15 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Inferencing.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Mode.scala | 1 |
3 files changed, 18 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala index de5c559bf..8238b3e34 100644 --- a/src/dotty/tools/dotc/typer/Implicits.scala +++ b/src/dotty/tools/dotc/typer/Implicits.scala @@ -41,11 +41,8 @@ object Implicits { /** Return those references in `refs` that are compatible with type `pt`. */ protected def filterMatching(pt: Type)(implicit ctx: Context): List[TermRef] = track("filterMatching") { - def result(implicit ctx: Context) = { - def refMatches(ref: TermRef) = isCompatible(normalize(ref), pt) - refs filter refMatches - } - result(ctx.fresh.withExploreTyperState) // create a defensive copy of ctx to avoid constraint pollution + def refMatches(ref: TermRef)(implicit ctx: Context) = isCompatible(normalize(ref), pt) + refs filter (ref => refMatches(ref)(ctx.fresh.withExploreTyperState)) // create a defensive copy of ctx to avoid constraint pollution } /** No further implicit conversions can be applied when searching for implicits. */ @@ -277,6 +274,11 @@ 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) { + pt match { + case pt: TypeVar => assert(pt.isInstantiated) //!!! DEBUG + case _ => + } + val initctx: Context = disableImplicits(ctx.fresh.withNewTyperState) def nestedContext = initctx.fresh.withNewTyperState @@ -293,7 +295,8 @@ trait Implicits { self: Typer => var generated: Tree = Ident(ref).withPos(pos) if (!argument.isEmpty) generated = typedUnadapted( - untpd.Apply(untpd.TypedSplice(generated), untpd.TypedSplice(argument) :: Nil), pt) + untpd.Apply(untpd.TypedSplice(generated), untpd.TypedSplice(argument) :: Nil), + pt)(ctx.fresh.addMode(Mode.RestrictedInterpolation)) val generated1 = interpolateAndAdapt(generated, pt) lazy val shadowing = typed(untpd.Ident(ref.name), ref)(nestedContext).tpe diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala index 8c7285883..651cb16f7 100644 --- a/src/dotty/tools/dotc/typer/Inferencing.scala +++ b/src/dotty/tools/dotc/typer/Inferencing.scala @@ -200,8 +200,11 @@ object Inferencing { * in type `tp` approximate it by its upper bound. */ def interpolateUndetVars(tp: Type, pos: Position): Unit = Stats.track("interpolateUndetVars") { + def qualifies(tvar: TypeVar) = + (pos contains tvar.pos) && + !((ctx.mode is Mode.RestrictedInterpolation) && (tvar.pos contains pos)) val vs = tp.variances(tvar => - (ctx.typerState.undetVars contains tvar) && (pos contains tvar.pos)) + (ctx.typerState.undetVars contains tvar) && qualifies(tvar)) var changed = false for ((tvar, v) <- vs) if (v != 0) { @@ -212,11 +215,11 @@ object Inferencing { if (changed) interpolateUndetVars(tp, pos) else - for (tvar <- ctx.typerState.undetVars - if (pos contains tvar.pos) && !(tvar.pos contains pos) && !(vs contains tvar)) { + for (tvar <- ctx.typerState.undetVars) + if (!(vs contains tvar) && qualifies(tvar)) { // println(s"instantiating non-occurring $tvar in $tp") - tvar.instantiate(fromBelow = true) - } + tvar.instantiate(fromBelow = true) + } } /** Instantiate undetermined type variables to that type `tp` is diff --git a/src/dotty/tools/dotc/typer/Mode.scala b/src/dotty/tools/dotc/typer/Mode.scala index 1890822b6..e126a794d 100644 --- a/src/dotty/tools/dotc/typer/Mode.scala +++ b/src/dotty/tools/dotc/typer/Mode.scala @@ -31,6 +31,7 @@ object Mode { val ImplicitsEnabled = newMode(2, "ImplicitsEnabled") val InSuperInit = newMode(3, "InSuperInit") + val RestrictedInterpolation = newMode(4, "RestrictedInterpolation") val PatternOrType = Pattern | Type }
\ No newline at end of file |