scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
231 stars 21 forks source link

type inference regression after analyzer plugins patch #7782

Closed scabug closed 10 years ago

scabug commented 11 years ago
package pack

object Test1 {
  import TestIteratee1._

  def foo(empty: Any): Any = ???

  foo(empty = ???)
}

object TestIteratee1
  extends TestEnumeratorTFunctions
     with TestEnumeratorPFunctions

trait TestEnumeratorT {
  def map[BB](f: Int => BB)
}

abstract class TestEnumeratorP[E, F[_]] {

  def test[B](f: Int => B): Any = {
    (null: TestEnumeratorT).map(f)
    ???
  }
}

trait TestEnumeratorPFunctions {
  def empty[E, F[_]]: TestEnumeratorP[E, F] = ???
}

trait TestEnumeratorTFunctions {
  def empty[E, F[_]](implicit a: Any): Any = ???
}
 /code/scala scalac-hash e67a039 /Users/jason/code/scratch3/src/main/scala/pack/TestEnumeratorP.scala
[info] e67a039 => /Users/jason/usr/scala-v2.11.0-M1-393-ge67a039
warning: there were 3 feature warnings; re-run with -feature for details
one warning found
  /code/scala scalac-hash f3cdf14 /Users/jason/code/scratch3/src/main/scala/pack/TestEnumeratorP.scala[info] f3cdf14 => /Users/jason/usr/scala-v2.10.0-463-gf3cdf14
warning: there were 3 feature warnings; re-run with -feature for details
one warning found
  /code/scala scalac-hash df8de9063 /Users/jason/code/scratch3/src/main/scala/pack/TestEnumeratorP.scala
[info] df8de9063 => /Users/jason/usr/scala-v2.11.0-M1-401-gdf8de90
/Users/jason/code/scratch3/src/main/scala/pack/TestEnumeratorP.scala:22: error: no type parameters for method map: (f: Int => BB)Unit exist so that it can be applied to arguments (Int => B)
 --- because ---
argument expression's type is not compatible with formal parameter type;
 found   : Int => B
 required: Int => ?BB
    (null: TestEnumeratorT).map(f)
                            ^
/Users/jason/code/scratch3/src/main/scala/pack/TestEnumeratorP.scala:22: error: type mismatch;
 found   : Int => B
 required: Int => BB
    (null: TestEnumeratorT).map(f)
                                ^
two errors found
  /code/scala git show df8de9063
commit df8de9063ce2008d2e23b46b6464abee03f75e5a
Merge: e67a039 f3cdf14
Author: Lukas Rytz <lukas.rytz@epfl.ch>
Date:   Mon Feb 4 11:32:14 2013 +0100

    Merge commit 'f3cdf146709e0dd98533ee77e8ca2566380cb932'

    Conflicts:
        src/compiler/scala/tools/nsc/typechecker/Contexts.scala
        src/compiler/scala/tools/nsc/typechecker/Namers.scala
        src/compiler/scala/tools/nsc/typechecker/Typers.scala
        src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
        src/reflect/scala/reflect/internal/AnnotationCheckers.scala
        src/reflect/scala/reflect/internal/Symbols.scala
scabug commented 11 years ago

Imported From: https://issues.scala-lang.org/browse/SI-7782?orig=1 Reporter: @retronym Affected Versions: 2.10.1, 2.11.0-M3 Other Milestones: 2.11.0-M6

scabug commented 11 years ago

@retronym said: Further reduced:

package pack

object Named {
  import O.empty
  def foo(empty: Any): Any = ???
  // is `empty` a named arg or an assignment? Checking for that has nasty side effects!
  foo(empty = ???)
}

object O {
  // order matters (!!!)
  def empty(implicit a: Any): Any = ???
  def empty[E]: C[E] = ???
}

abstract class C[E] {
  def foo[BB](f: BB)
  def test[B](f: B): Any = foo(f)
}
scabug commented 11 years ago

@retronym said (edited on Aug 26, 2013 9:58:29 AM UTC): Okay, this is skolem related.

package pack

object Test {
  import O.empty
  empty // this will trigger PolyTypeCompleter of `test`
        // which picks up `skolemizationLevel = 1` from the in-flight `isAsSpecific` check
        // that happens to be computing `Any <:< pack.this.C[E] forSome { E }`
}

object O {
  // order matters (!!!)
  def empty(implicit a: Any): Any = ???
  def empty[E]: C[E] = ???
}

abstract class C[E] {
  def foo[BB](f: BB)
  def test[B](f: B): Any = foo(f)
  // error: no type parameters for method foo: (<param> f: BB)scala.this.Unit exist so that it can be applied to arguments (B&1)
  // --- because ---
  // argument expression's type is not compatible with formal parameter type;
  // found   : B&1
  // required: ?BB
}
scabug commented 11 years ago

@retronym said: 2.10.2 is also susceptible to the problem:

package pack

object Test {
  import O.empty
  empty // this will trigger completion of `test`
        // with skolemizationLevel = 1
}

object O {
  // order matters (!!!)
  // def empty(implicit a: Any): Any = ???
  def empty[E]: C[E] = ???
   def empty(implicit a: Any): Any = ???
}

abstract class C[E] {
  def foo[BB](f: BB)
  def test[B](f: B): Any = foo(f)
  // error: no type parameters for method foo: (<param> f: BB)scala.this.Unit exist so that it can be applied to arguments (B&1)
  // --- because ---
  // argument expression's type is not compatible with formal parameter type;
  // found   : B&1
  // required: ?BB
}

I had to switch the order of the empty methods around as a inferExprAlternative seems to try these in a a different order in master, and if the completers trigger earlier outside of:

      case ExistentialType(_, _) =>
        try {
          skolemizationLevel += 1
          isSubType(tp1.skolemizeExistential, tp2, depth)
        } finally {
          skolemizationLevel -= 1
        }

This test case regresses at: b74c33eb860622e363 "SI-1803, plus documentation and cleanups in Namers, mainly in typeSig".

I think the fix is to force the level of skolems derived in PolyTypeCompleter to 0.

scabug commented 11 years ago

@retronym said: PR: https://github.com/scala/scala/pull/2876