aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-01-09 23:41:46 +0100
committerMartin Odersky <odersky@gmail.com>2014-01-09 23:41:46 +0100
commitd998a3287b465e99340c50f01680f8b3b9b87218 (patch)
treeba30e46fdaebe7544a8dbd45a2afb994ad4762dc /src/dotty/tools
parent6135d51b35ec20199231984e978a6be99169d351 (diff)
downloaddotty-d998a3287b465e99340c50f01680f8b3b9b87218.tar.gz
dotty-d998a3287b465e99340c50f01680f8b3b9b87218.tar.bz2
dotty-d998a3287b465e99340c50f01680f8b3b9b87218.zip
Refine eligibility
Because eligibility is tested in a context which is different from the implicit search context, we cannot assume that type variables have their constraint recorded. So we have to approximate subtype tests with PolyParams which are not in the constraint set.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala7
-rw-r--r--src/dotty/tools/dotc/typer/Implicits.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Mode.scala2
3 files changed, 8 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 0969f814f..47e554968 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -3,6 +3,7 @@ package dotc
package core
import Types._, Contexts._, Symbols._, Flags._, Names._, NameOps._
+import typer.Mode
import Decorators._
import StdNames.{nme, tpnme}
import collection.mutable
@@ -119,6 +120,8 @@ class TypeComparer(initctx: Context) extends DotClass {
case bound: AndOrType if fromBelow != bound.isAnd =>
addConstraint(param, bound.tp1, fromBelow) &&
addConstraint(param, bound.tp2, fromBelow)
+ case bound: WildcardType =>
+ true
case _ =>
addConstraint1(param, bound, fromBelow)
}
@@ -254,7 +257,7 @@ class TypeComparer(initctx: Context) extends DotClass {
tp2 == tp1 ||
isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || {
if (constraint contains tp2) addConstraint(tp2, tp1.widen.dealias.stripTypeVar, fromBelow = true)
- else secondTry(tp1, tp2)
+ else (ctx.mode is Mode.TypevarsMissContext) || secondTry(tp1, tp2)
}
case tp2: BoundType =>
tp2 == tp1 || secondTry(tp1, tp2)
@@ -293,7 +296,7 @@ class TypeComparer(initctx: Context) extends DotClass {
ctx.typerState.isGlobalCommittable)
ctx.log(s"!!! instantiating to Nothing: $tp1")
if (constraint contains tp1) addConstraint(tp1, tp2.dealias.stripTypeVar, fromBelow = false)
- else thirdTry(tp1, tp2)
+ else (ctx.mode is Mode.TypevarsMissContext) || thirdTry(tp1, tp2)
}
case tp1: BoundType =>
tp1 == tp2 || secondTry(tp1, tp2)
diff --git a/src/dotty/tools/dotc/typer/Implicits.scala b/src/dotty/tools/dotc/typer/Implicits.scala
index 4526c3582..aaf0d2e76 100644
--- a/src/dotty/tools/dotc/typer/Implicits.scala
+++ b/src/dotty/tools/dotc/typer/Implicits.scala
@@ -44,7 +44,7 @@ object Implicits {
def refMatches(ref: TermRef)(implicit ctx: Context) =
(ref.symbol isAccessibleFrom ref.prefix) && isCompatible(normalize(ref, pt), pt)
- refs filter (refMatches(_)(ctx.fresh.withExploreTyperState)) // create a defensive copy of ctx to avoid constraint pollution
+ refs filter (refMatches(_)(ctx.fresh.withExploreTyperState.addMode(Mode.TypevarsMissContext))) // create a defensive copy of ctx to avoid constraint pollution
}
/** No further implicit conversions can be applied when searching for implicits. */
diff --git a/src/dotty/tools/dotc/typer/Mode.scala b/src/dotty/tools/dotc/typer/Mode.scala
index b11d4dc7d..65afbd7c8 100644
--- a/src/dotty/tools/dotc/typer/Mode.scala
+++ b/src/dotty/tools/dotc/typer/Mode.scala
@@ -31,5 +31,7 @@ object Mode {
val ImplicitsEnabled = newMode(2, "ImplicitsEnabled")
val InferringReturnType = newMode(3, "InferencingReturnType")
+ val TypevarsMissContext = newMode(4, "TypevarsMissContext")
+
val PatternOrType = Pattern | Type
} \ No newline at end of file