Aladdin - Scala Bugtracking
[#1085] project: compiler priority: high category: bug
submitter assigned to status date submitted
Adriaan Adriaan fixed 2007-05-03 11:41:58.0
subject asSeenFrom problem with refinements that include type constructor members
code
trait Functor[a] {
  type MyType[a]
}

object Test {
  def listFunctor[a]: Functor[a]{type MyType[x]=List[x]} = new Functor[a] {
    type MyType[t]=List[t]
  }
}
// pending/pos/bug1085.scala
what happened
Compiler (trunk r10946 ) crashes
Exception in thread "main" java.lang.Error: x in  cannot be instantiated from Functor[a]{type MyType\
[x] = List[x]}
        at scala.tools.nsc.symtab.Types$AsSeenFromMap.throwError$0(Types.scala:1882)
        at scala.tools.nsc.symtab.Types$AsSeenFromMap.instParam$0(Types.scala:1885)
        at scala.tools.nsc.symtab.Types$AsSeenFromMap.toInstance$0(Types.scala:1899)
        at scala.tools.nsc.symtab.Types$AsSeenFromMap.apply(Types.scala:1905)
        at scala.tools.nsc.symtab.Types$AsSeenFromMap.apply(Types.scala:1840)
        at scala.tools.nsc.symtab.Types$TypeMap$$anonfun$28.apply(Types.scala:1807)
        at scala.tools.nsc.symtab.Types$TypeMap$$anonfun$28.apply(Types.scala:1803)
        at scala.tools.nsc.symtab.Types$class.map2Conserve(Types.scala:2556)
        at scala.tools.nsc.symtab.SymbolTable.map2Conserve(SymbolTable.scala:10)
        at scala.tools.nsc.symtab.Types$TypeMap.mapOverArgs(Types.scala:1803)
        at scala.tools.nsc.symtab.Types$TypeMap.mapOver(Types.scala:1733)
        at scala.tools.nsc.symtab.Types$AsSeenFromMap.apply(Types.scala:1907)
        at scala.tools.nsc.symtab.Types$Type.asSeenFrom(Types.scala:282)
        at scala.tools.nsc.symtab.Types$class.transform$0(Types.scala:1547)
        at scala.tools.nsc.symtab.Types$class.typeRef(Types.scala:1555)
        at scala.tools.nsc.symtab.SymbolTable.typeRef(SymbolTable.scala:10)
        at scala.tools.nsc.symtab.Types$class.typeRef(Types.scala:1540)
        at scala.tools.nsc.symtab.SymbolTable.typeRef(SymbolTable.scala:10)
        at scala.tools.nsc.symtab.Symbols$TypeSymbol.tpe(Symbols.scala:1160)
        at scala.tools.nsc.symtab.classfile.Pickler$Pickle.putSymbol(Pickler.scala:108)
...
what expected succesful compilation Martin, I already had a look, as it's related to my extension, but it seems like a problem with asSeenFrom that I don't fully understand. I'll keep looking, though. My first intuition was that the transform methods in TypeRef (transform, transformInfo, relativeInfo) and in the typeRef method (transform), should not start looking in sym.owner when using asSeenFrom to instantiate the type params. They should start in sym -- the type member -- as the type member itself declares the type parameters -- but changing these sym.owner's to sym breaks other things. For example, the assumption in asSeenFrom that the symbol in which the search must start is a class (?). On the other hand, why should x be instantiated at all? Maybe toInstance in asSeenFrom should check whether it's a higher-order type param that can't be instantiated, and don't throw an error in that case?
[back to overview]
Changes of this bug report
Martin  edited on  2007-07-17 18:40:04.0
I am not convinced that asSeenFrom is to blame. If you turn -debug on you will find that the owner of x is , i.e. the Functor[a] { type ... } type. Should it not rather be `MyType'?
Adriaan  edited on  2007-07-17 18:52:48.0
ok, I'll try to track down where the owner gets messed up
Adriaan  edited on  2007-07-17 20:46:26.0
Well, it seems the culprit was pickling:
    def putSymbol(sym: Symbol) {
      if (putEntry(sym)) {
        if (isLocal(sym)) {
  // 
          if (sym.thisSym.tpeHK != sym.tpeHK) // was: sym.thisSym.tpe != sym.tpe
            putType(sym.typeOfThis);
before, the .tpe call on the symbol produced dummy type arguments, which were then instantiated apparently. Now, no type arguments are produced, which seems ok as it's just an equality check, but I don't see the whole picture wrt Pickling here, so maybe this is not the right fix (I still don't know why the owner was wrong, so maybe this is just a stopgap). Anyway, I've committed it (r12347), but Martin: please review and close the report if the solution is ok.
Adriaan  edited on  2007-07-18 11:55:23.0
cf Martin's mail on 18 July 2007 11:45
Adriaan  edited on  2007-07-24 18:36:23.0
I re-opened this bug, because I encountered it in a different context. I tracked down why the higher-order type param symbols have the wrong owner:
// in PolyType
 override def cloneInfo(owner: Symbol) = {
      val tparams = cloneSymbols(typeParams, owner) // @M: cloneSymbols sets *all* cloned symbols' owner to `owner'... should only do that for top-level symbols, not their children
      PolyType(tparams, resultType.substSym(typeParams, tparams))
    }
I have to take a closer look at cloning before changing this though. (Just changing the first line to
      val tparams = cloneSymbols(typeParams)
does the trick in my particular case... that's probably too easy a fix though ;-))
Adriaan  edited on  2007-08-22 15:52:10.0
probably related to 1210, fixed now