aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2017-04-08 22:51:16 +0200
committerGuillaume Martres <smarter@ubuntu.com>2017-04-08 23:26:05 +0200
commitb159489576fc7afdee5b2d93e9465dbc87f8069e (patch)
tree3387b92f511c18fa91a8417b6b74a43d798e4a19
parent4d76265fac7edafc2fcf29ce6873fdb252fbba0d (diff)
downloaddotty-b159489576fc7afdee5b2d93e9465dbc87f8069e.tar.gz
dotty-b159489576fc7afdee5b2d93e9465dbc87f8069e.tar.bz2
dotty-b159489576fc7afdee5b2d93e9465dbc87f8069e.zip
Fix #2201: Less aggressive type application reduction for better inference
Previously we believed that reducing type applications did not affect type inference as long as the reduced type constructor had the same arity as the unreduced one, for example reducing `Foo[X, Y]` is fine when `Foo` is defined as: type Foo[A, B] = Bar[A, B] but not when it's defined as: type Foo[A] = Bar[A, A] But this is not a sufficient condition: the bounds of the type constructor arguments also matter for type inference, so we need to be more strict and disallow reductions in cases like: type Foo[A, B] = Bar[B, A] and: type Foo[A, B] = Bar[A, Int]
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeApplications.scala9
-rw-r--r--tests/pos/i2201a.scala8
-rw-r--r--tests/pos/i2201b.scala14
-rw-r--r--tests/pos/i2201c.scala11
4 files changed, 39 insertions, 3 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
index 23c3f96cc..94b726491 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -391,9 +391,12 @@ class TypeApplications(val self: Type) extends AnyVal {
if (!args.exists(_.isInstanceOf[TypeBounds])) {
val followAlias = Config.simplifyApplications && {
dealiased.resType match {
- case AppliedType(tyconBody, _) =>
- sameLength(dealiased.typeParams, tyconBody.typeParams)
- // Reducing is safe for type inference, as kind arity of type constructor does not change
+ case AppliedType(tyconBody, dealiasedArgs) =>
+ // Reduction should not affect type inference when it's
+ // just eta-reduction (ignoring variance annotations).
+ // See i2201*.scala for examples where more aggressive
+ // reduction would break type inference.
+ dealiased.paramRefs == dealiasedArgs
case _ => false
}
}
diff --git a/tests/pos/i2201a.scala b/tests/pos/i2201a.scala
new file mode 100644
index 000000000..165f0a76e
--- /dev/null
+++ b/tests/pos/i2201a.scala
@@ -0,0 +1,8 @@
+class Foo[T]
+
+class Fix[F[_]](unfix: F[Fix[F]])
+object DocTree {
+ type Const[T] = Foo[Int]
+ type FixConst = Fix[Const]
+ def docTree(s: Const[FixConst]): FixConst = new Fix(s)
+}
diff --git a/tests/pos/i2201b.scala b/tests/pos/i2201b.scala
new file mode 100644
index 000000000..4aafc0d28
--- /dev/null
+++ b/tests/pos/i2201b.scala
@@ -0,0 +1,14 @@
+trait X
+trait Y
+
+object Test {
+ type One[A <: X, B <: Y]
+
+ type Two[TA <: Y, TB <: X] = One[TB, TA]
+
+ def foo[M[_ <: Y, _ <: X]](x: M[_ <: Y, _ <: X]) = x
+
+ val a: Two[Y, X] = ???
+
+ foo(a)
+}
diff --git a/tests/pos/i2201c.scala b/tests/pos/i2201c.scala
new file mode 100644
index 000000000..91f2529d9
--- /dev/null
+++ b/tests/pos/i2201c.scala
@@ -0,0 +1,11 @@
+object Test {
+ implicit val theAnswer: Int = 42
+
+ type Swap[A, B] = (B, A)
+
+ def foo[M[_, _], T, S](x: M[T, S])(implicit ev: T) = ev
+
+ val a: Swap[Int, String] = ("hi", 1)
+
+ foo(a)
+}