scala / bug

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

2.8: Assertion Error Erasure$$Eraser.cast(Erasure.scala:442) #2331

Closed scabug closed 13 years ago

scabug commented 15 years ago

While trying to find a minimal test case for #2216, I ran into this error after passing a null as an argument to an implicit parameter list.

It's not a blocking problem.

code and console output attached.

scabug commented 15 years ago

Imported From: https://issues.scala-lang.org/browse/SI-2331?orig=1 Reporter: @retronym Attachments:

scabug commented 15 years ago

@retronym said: I meant to reference #2316, not #2216.

scabug commented 15 years ago

@cunei said: Still there as of r18652.

scabug commented 14 years ago

@paulp said: Cannot determine why this is assigned to me unless it is for me to pinpoint when regression was introduced. After applying state of the art regression finding technology I have determined this: it's not a regression, it crashes the same way since at least 2.7.1.

scabug commented 14 years ago

@hubertp said: Here is a smaller example. The bug is not related to nulls nor implicits.

  trait Promise[A] extends (() => A)  

  object Promise {
    def promise[A]:Promise[A] = error("omitted")
  }

  trait Bind[Z[_]] {
    def bind[B]: Z[B]
  }

  object Bind {
     val PromiseBind = new Bind[Promise] {
       def bind[B] = error("omitted")
     }
   }

  object crash {
    def fmap[B]:Promise[B] = {
      var b = Bind.PromiseBind
      b.bind
    }
  }

Giving the type explicitly to PromiseBind or to bind solves the problem.

scabug commented 14 years ago

@odersky said: This seems to be related to higher-kinded types. At least a normalize assertion fails.

scabug commented 14 years ago

@adriaanm said: The failing normalize was testing an invariant about alias types being expanded by the time you get to erasure. The weird thing is, if you print the pt and pt.normalize for which (pt eq pt.normalize) does not hold, you get:

<root>SI-2#<empty>SI-4#BindSI-7363 and <root>SI-2#<empty>SI-4#BindSI-7363

There's definitely something that's going awry, though.. commenting out the assertion allows the compiler to get to a more serious one in genicode:

fatal: <refinement> has owner value PromiseBindSI-8942, but a class owner is required

I won't be able to fix this before I get back, so I'll assign back to you, Martin. Feel free to bounce it back by 13 april ;-)

scabug commented 14 years ago

@odersky said: I was that far already. But since it seems to invole HK types, I bounce it back.

scabug commented 14 years ago

@adriaanm said: Smaller test case that seems to indicate it's not directly caused by higher-kinded stuff, but rather by type inference for anonymous classes...

trait Bind {
  def bind[B]: B
}

object Test {
  val bind /*: Bind --> no crash*/ = new Bind {
    def bind[B]: Nothing /*: B --> no crash*/ = error("omitted")
  }

  bind.bind[Nothing]
}
scabug commented 14 years ago

@adriaanm said: I think the problem is in adaptMember in erasure:

        case Select(qual, name) if (name != nme.CONSTRUCTOR) =>
[...]
            } else if (!(qual1.isInstanceOf[Super] || (qual1.tpe.typeSymbol isSubClass tree.symbol.owner))) {
              assert(tree.symbol.owner != ArrayClass)
-              qual1 = cast(qual1, tree.symbol.owner.tpe)
+              qual1 = cast(qual1, tree.symbol.owner.tpe.normalize) // SI-2331
            }
-            treeCopy.Select(tree, qual1, name)
+           treeCopy.Select(tree, qual1, name) setSymbol NoSymbol // SI-2331: force re-typecheck as name may now refer to a different symbol
scabug commented 14 years ago

@adriaanm said: of course it was more subtle than that... think I finally found it: the pre-transform in Erasure did not correctly recurse in the case of a TypeApply.

It simply returned the function, which might very well have been, say, a Select node, which had to be erased in case the qualifier's type is a refinement.

scabug commented 14 years ago

@adriaanm said: (In r22508) closes #2331: the pre-transform in Erasure did not correctly recurse in the case of a TypeApply.

It simply returned the function, which might very well have been, say, a Select node, which had to be erased in case the qualifier's type is a refinement.

(sorry about the whitespace changes)

review by odersky