From 733b3220c9c099fcb68e09c37251bea8023198f2 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 7 Sep 2013 11:24:11 +0200 Subject: 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. --- src/reflect/scala/reflect/internal/Types.scala | 4 ++-- test/files/pos/t7815.scala | 30 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 test/files/pos/t7815.scala 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 + } +} -- cgit v1.2.3