diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-09 23:41:46 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-09 23:41:46 +0100 |
commit | d998a3287b465e99340c50f01680f8b3b9b87218 (patch) | |
tree | ba30e46fdaebe7544a8dbd45a2afb994ad4762dc /src/dotty/tools | |
parent | 6135d51b35ec20199231984e978a6be99169d351 (diff) | |
download | dotty-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.scala | 7 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Implicits.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Mode.scala | 2 |
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 |