diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2013-09-07 11:24:11 +0200 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2013-09-07 11:51:30 +0200 |
commit | 733b3220c9c099fcb68e09c37251bea8023198f2 (patch) | |
tree | c01009068ee56bf312a1f593b7c47670b8b24505 | |
parent | d46519da657ada39d9928308709cdb80ddcd53ce (diff) | |
download | scala-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.scala | 4 | ||||
-rw-r--r-- | test/files/pos/t7815.scala | 30 |
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 + } +} |