Skip to content
This repository
Browse code

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.
  • Loading branch information...
commit 733b3220c9c099fcb68e09c37251bea8023198f2 1 parent d46519d
Jason Zaugg retronym authored
4 src/reflect/scala/reflect/internal/Types.scala
@@ -2626,7 +2626,7 @@ trait Types extends api.Types { self: SymbolTable =>
2626 2626
2627 2627 private var isdepmeth: ThreeValue = UNKNOWN
2628 2628 override def isDependentMethodType: Boolean = {
2629   - if (isdepmeth == UNKNOWN) isdepmeth = fromBoolean(IsDependentCollector.collect(resultType))
  2629 + if (isdepmeth == UNKNOWN) isdepmeth = fromBoolean(IsDependentCollector.collect(resultType.dealias))
2630 2630 toBoolean(isdepmeth)
2631 2631 }
2632 2632
@@ -4807,7 +4807,7 @@ trait Types extends api.Types { self: SymbolTable =>
4807 4807 object IsDependentCollector extends TypeCollector(false) {
4808 4808 def traverse(tp: Type) {
4809 4809 if (tp.isImmediatelyDependent) result = true
4810   - else if (!result) mapOver(tp)
  4810 + else if (!result) mapOver(tp.dealias)
4811 4811 }
4812 4812 }
4813 4813
30 test/files/pos/t7815.scala
... ... @@ -0,0 +1,30 @@
  1 +import language.higherKinds
  2 +
  3 +trait Foo[A <: AnyRef] {
  4 + type Repr
  5 + def f(a: A): Repr
  6 + def g(a: A): Option[Repr]
  7 +
  8 + type M[X]
  9 + def m(a: A): M[a.type]
  10 +
  11 + type Id[X] = X
  12 + def n(a: A): Id[(Repr, M[a.type])]
  13 +
  14 +}
  15 +
  16 +object Foo {
  17 + type Aux[A <: AnyRef, B] = Foo[A] { type Repr = B; type M[X] = Int }
  18 +
  19 +}
  20 +
  21 +object Main extends App {
  22 + def mapWithFoo[A <: AnyRef, B](as: List[A])(implicit foo: Foo.Aux[A, B]) = {
  23 + // Should be Eta expandable because the result type of `f` is not
  24 + // dependant on the value, it is just `B`.
  25 + as map foo.f
  26 + as map foo.g
  27 + as map foo.m
  28 + as map foo.n
  29 + }
  30 +}

0 comments on commit 733b322

Please sign in to comment.
Something went wrong with that request. Please try again.