aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala15
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala13
-rw-r--r--src/dotty/tools/dotc/typer/Mode.scala1
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