scala / bug

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

ClassCastException in compiler when defining a package with a name shadowed by member of package object #9094

Open scabug opened 9 years ago

scabug commented 9 years ago

Something about compiler-internal CCEs makes me submit this for posterity.

package object p {
  def free[A] = free.Free
}
package p.free {
  object Free
}
error: java.lang.ClassCastException: scala.reflect.internal.Trees$TypeApply cannot be cast to scala.reflect.internal.Trees$RefTree
    at scala.tools.nsc.typechecker.Typers$Typer.typedPackageDef$1(Typers.scala:4915)
    at scala.tools.nsc.typechecker.Typers$Typer.typedMemberDef$1(Typers.scala:5211)
    at scala.tools.nsc.typechecker.Typers$Typer.typed1(Typers.scala:5258)
    at scala.tools.nsc.typechecker.Typers$Typer.runTyper$1(Typers.scala:5295)
    at scala.tools.nsc.typechecker.Typers$Typer.scala$tools$nsc$typechecker$Typers$Typer$$typedInternal(Typers.scala:5322)
    at scala.tools.nsc.typechecker.Typers$Typer.body$2(Typers.scala:5269)
    at scala.tools.nsc.typechecker.Typers$Typer.typed(Typers.scala:5273)
scabug commented 9 years ago

Imported From: https://issues.scala-lang.org/browse/SI-9094?orig=1 Reporter: @paulp Affected Versions: 2.11.5

scabug commented 9 years ago

@retronym said (edited on Feb 19, 2015 10:30:18 PM UTC): I took a look at this one thinking it would be low-hanging fruit, but it is actually pretty subtle.

      def typedPackageDef(pdef0: PackageDef) = {
        val pdef = treeCopy.PackageDef(pdef0, pdef0.pid, pluginsEnterStats(this, pdef0.stats))
        val pid1 = typedQualifier(pdef.pid).asInstanceOf[RefTree]
        assert(sym.moduleClass ne NoSymbol, sym)

When we typecheck p.free with typedQualifer, we end up with a reference to p.package.free, a Select rather than RefTree.

We could easily enough gracefully error-out at this point, but that isn't the right semantic. It isn't an error to shadow a top level class or object with a member of the package object, so technically it shouldn't be an error to shadow a package. So along these lines, we might need a new typing Mode that only binds identifiers to package modules, and use that instead of typedQualifer.

But given that no outsider will actually be able to use the defiintions in package p.free due to shadowing, it seems doubtful that we should bend over backwards to deal with this situation. Maybe it is enough to pattern match on the result of typedQualifier and issue an implementation restriction.

Demoting this one to minor in any case.

scabug commented 9 years ago

@paulp said: Select is a RefTree. It has a TypedApply rather than a RefTree. Presumably that's p.package.free[A]. Anyway, I agree it's of minor importance, but I never could get behind the whole blind casting business. Must be something in my upbringing.