summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2013-09-07 11:24:11 +0200
committerJason Zaugg <jzaugg@gmail.com>2013-09-07 11:51:30 +0200
commit733b3220c9c099fcb68e09c37251bea8023198f2 (patch)
treec01009068ee56bf312a1f593b7c47670b8b24505
parentd46519da657ada39d9928308709cdb80ddcd53ce (diff)
downloadscala-733b3220c9c099fcb68e09c37251bea8023198f2.tar.gz
scala-733b3220c9c099fcb68e09c37251bea8023198f2.tar.bz2
scala-733b3220c9c099fcb68e09c37251bea8023198f2.zip
SI-7815 Dealias before deeming method type as dependent
To enable eta-expansion of method types seen from a prefix that renders the result type as independent from the parameter symbols. The enclosed test shows that we dealias types before checking dependence, and that we do this deeply (e.g. type arguments are also dealised.) An existing test, neg/error_dependentMethodTpeConversionToFunction, confirms that bona-fide dependent methods are still prohibited from eta expansion.
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala4
-rw-r--r--test/files/pos/t7815.scala30
2 files changed, 32 insertions, 2 deletions
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index cfa6f927b5..c684f4d690 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2626,7 +2626,7 @@ trait Types extends api.Types { self: SymbolTable =>
private var isdepmeth: ThreeValue = UNKNOWN
override def isDependentMethodType: Boolean = {
- if (isdepmeth == UNKNOWN) isdepmeth = fromBoolean(IsDependentCollector.collect(resultType))
+ if (isdepmeth == UNKNOWN) isdepmeth = fromBoolean(IsDependentCollector.collect(resultType.dealias))
toBoolean(isdepmeth)
}
@@ -4807,7 +4807,7 @@ trait Types extends api.Types { self: SymbolTable =>
object IsDependentCollector extends TypeCollector(false) {
def traverse(tp: Type) {
if (tp.isImmediatelyDependent) result = true
- else if (!result) mapOver(tp)
+ else if (!result) mapOver(tp.dealias)
}
}
diff --git a/test/files/pos/t7815.scala b/test/files/pos/t7815.scala
new file mode 100644
index 0000000000..12a434c5b0
--- /dev/null
+++ b/test/files/pos/t7815.scala
@@ -0,0 +1,30 @@
+import language.higherKinds
+
+trait Foo[A <: AnyRef] {
+ type Repr
+ def f(a: A): Repr
+ def g(a: A): Option[Repr]
+
+ type M[X]
+ def m(a: A): M[a.type]
+
+ type Id[X] = X
+ def n(a: A): Id[(Repr, M[a.type])]
+
+}
+
+object Foo {
+ type Aux[A <: AnyRef, B] = Foo[A] { type Repr = B; type M[X] = Int }
+
+}
+
+object Main extends App {
+ def mapWithFoo[A <: AnyRef, B](as: List[A])(implicit foo: Foo.Aux[A, B]) = {
+ // Should be Eta expandable because the result type of `f` is not
+ // dependant on the value, it is just `B`.
+ as map foo.f
+ as map foo.g
+ as map foo.m
+ as map foo.n
+ }
+}