aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-09-24 16:43:40 +0200
committerMartin Odersky <odersky@gmail.com>2015-10-01 19:34:14 +0200
commit241065192926524292f950288518533429297666 (patch)
treed2b6ff0d5c6cf7b0146ac5bb3a68f7f40a9242dd /src
parent2d6d432001bb237897918a05bd3e82be87dc8a11 (diff)
downloaddotty-241065192926524292f950288518533429297666.tar.gz
dotty-241065192926524292f950288518533429297666.tar.bz2
dotty-241065192926524292f950288518533429297666.zip
Freeze constraints when checking parameter matching and subsumption.
Checking whether two alternatives are the same should not unify them by instantiating type variables.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/ConstraintHandling.scala8
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala6
2 files changed, 11 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 6f0377a4d..577b958c8 100644
--- a/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -23,6 +23,7 @@ trait ConstraintHandling {
implicit val ctx: Context
protected def isSubType(tp1: Type, tp2: Type): Boolean
+ protected def isSameType(tp1: Type, tp2: Type): Boolean
val state: TyperState
import state.constraint
@@ -111,6 +112,13 @@ trait ConstraintHandling {
finally frozenConstraint = saved
}
+ final def isSameTypeWhenFrozen(tp1: Type, tp2: Type): Boolean = {
+ val saved = frozenConstraint
+ frozenConstraint = true
+ try isSameType(tp1, tp2)
+ finally frozenConstraint = saved
+ }
+
/** Test whether the lower bounds of all parameters in this
* constraint are a solution to the constraint.
*/
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index 8b2eb9cbf..59d4898e6 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -685,7 +685,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case formal1 :: rest1 =>
formals2 match {
case formal2 :: rest2 =>
- (isSameType(formal1, formal2)
+ (isSameTypeWhenFrozen(formal1, formal2)
|| isJava1 && (formal2 isRef ObjectClass) && (formal1 isRef AnyClass)
|| isJava2 && (formal1 isRef ObjectClass) && (formal2 isRef AnyClass)) &&
matchingParams(rest1, rest2, isJava1, isJava2)
@@ -1059,7 +1059,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp1: ClassInfo =>
tp2 match {
case tp2: ClassInfo =>
- isSubType(tp1.prefix, tp2.prefix) || (tp1.cls.owner derivesFrom tp2.cls.owner)
+ isSubTypeWhenFrozen(tp1.prefix, tp2.prefix) || (tp1.cls.owner derivesFrom tp2.cls.owner)
case _ =>
false
}
@@ -1075,7 +1075,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
tp2 match {
case tp2: MethodType =>
def asGoodParams(formals1: List[Type], formals2: List[Type]) =
- (formals2 corresponds formals1)(isSubType)
+ (formals2 corresponds formals1)(isSubTypeWhenFrozen)
asGoodParams(tp1.paramTypes, tp2.paramTypes) &&
(!asGoodParams(tp2.paramTypes, tp1.paramTypes) ||
isAsGood(tp1.resultType, tp2.resultType))