aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-08-26 16:38:37 +0200
committerMartin Odersky <odersky@gmail.com>2016-08-26 17:57:09 +0200
commit36648547105bc8ac53dd63a03821a27243af13cd (patch)
tree87aa262b01aa983088e7f3349da2cc380308f15b /src/dotty/tools
parenteef9be9817f5c0516e221aab1d14d748a12b386c (diff)
downloaddotty-36648547105bc8ac53dd63a03821a27243af13cd.tar.gz
dotty-36648547105bc8ac53dd63a03821a27243af13cd.tar.bz2
dotty-36648547105bc8ac53dd63a03821a27243af13cd.zip
Handle complex context merging cases
Test case in isApplicableSafe.scala. It turns out that this requires a context merge using the new `&' operator. Sequence of actions: 1) Typecheck argument in typerstate 1. 2) Cache argument. 3) Evolve same typer state (to typecheck other arguments, say) leading to a different constraint. 4) Take typechecked argument in same state. It turns out that the merge in TyperState is needed not just for isApplicableSafe but also for (e.g. erased-lubs.scala) as well as many parts of dotty itself.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/TyperState.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Inferencing.scala3
2 files changed, 7 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala
index 4b3c1554d..a7ad6824f 100644
--- a/src/dotty/tools/dotc/core/TyperState.scala
+++ b/src/dotty/tools/dotc/core/TyperState.scala
@@ -96,7 +96,8 @@ extends TyperState(r) {
override def reporter = myReporter
- private var myConstraint: Constraint = previous.constraint
+ private val previousConstraint = previous.constraint
+ private var myConstraint: Constraint = previousConstraint
override def constraint = myConstraint
override def constraint_=(c: Constraint)(implicit ctx: Context) = {
@@ -129,8 +130,9 @@ extends TyperState(r) {
override def commit()(implicit ctx: Context) = {
val targetState = ctx.typerState
assert(isCommittable)
- if (targetState eq previous) targetState.constraint = constraint
- else targetState.constraint &= constraint
+ targetState.constraint =
+ if (targetState.constraint eq previousConstraint) constraint
+ else targetState.constraint & constraint
constraint foreachTypeVar { tvar =>
if (tvar.owningState eq this)
tvar.owningState = targetState
diff --git a/src/dotty/tools/dotc/typer/Inferencing.scala b/src/dotty/tools/dotc/typer/Inferencing.scala
index 7c61f8c23..719e8d7fc 100644
--- a/src/dotty/tools/dotc/typer/Inferencing.scala
+++ b/src/dotty/tools/dotc/typer/Inferencing.scala
@@ -78,7 +78,8 @@ object Inferencing {
def apply(x: Boolean, tp: Type): Boolean = tp.dealias match {
case _: WildcardType | _: ProtoType =>
false
- case tvar: TypeVar if !tvar.isInstantiated =>
+ case tvar: TypeVar
+ if !tvar.isInstantiated && ctx.typerState.constraint.contains(tvar) =>
force.appliesTo(tvar) && {
val direction = instDirection(tvar.origin)
if (direction != 0) {