Nikolay edited on 2007-07-12 12:09:03.0
|
|
Adriaan edited on 2007-07-12 15:11:02.0
|
well, first off, this looks like an erroneous program, but anyway, I must've made a mistake somewhere in normalize... :-(
Furthermore, it looks like two bugs in one. First, it can be simplified to:
object Test {
def id[T](f: T => T): T = error("bla")
abstract class M { self =>
type Settings
type selfType = M {type Settings = self.Settings}
val v: selfType = id[M.this.selfType](_.v)
}
}
Then, if I apply a quick fix to normalize in TypeRef:
override def normalize = {
if (sym.isAliasType) {
if (sym.info.typeParams.length == args.length) {
var xform=transform(sym.info.resultType)
if(xform eq this) this // bug1210 -- why is this necessary? I thought for tp=TypeRef(_, sym, _)
// sym.isAliasType implies !(sym.info.resultType eq tp)
else xform.normalize // cycles have been checked in typeRef (?)
The compiler doesn't crash anymore, but gives the following error
/Users/adriaan/src/scala/trunk/test/files/neg/bug1210.scala:8: error: type mismatch;
found : x$0.selfType
required: M.this.selfType
val v: selfType = id[M.this.selfType](_.v)
^
one error found
Note that x$0 seems to escape its scope!
If we rewrite using type parameters instead of type members:
object Test {
def id[T](f: T => T): T = error("bla")
abstract class M[Settings] {
type selfType = M[Settings]
val v: selfType = id[M.this.selfType](_.v)
}
}
the compiler crashes like this:
Exception in thread "main" java.lang.Error: Settings in class M cannot be instantiated from ?*x$0.type
at scala.tools.nsc.symtab.Types$AsSeenFromMap.throwError$0(Types.scala:2114)
at scala.tools.nsc.symtab.Types$AsSeenFromMap.toInstance$0(Types.scala:2136)
$x0 tries to escape its scope again, but here it crashes asSeenFrom...
|
Adriaan edited on 2007-07-20 11:32:28.0
|
I committed the quick fix mentioned above in r12373, so the error wrt the escaping variable becomes apparent (test file in pending/neg/bug1210.scala)
|
Martin edited on 2007-07-26 01:04:39.0
|
|
Martin edited on 2007-07-26 11:00:15.0
|
|
Stephane edited on 2007-07-27 13:19:47.0
|
fixed in rev 12431
|
Adriaan edited on 2007-08-20 10:29:31.0
|
re-opened based on discussion with Martin @ ECOOP (fix is pending)
|
Adriaan edited on 2007-08-21 00:06:29.0
|
proposed fix is in r12604, Martin: please review
|
Adriaan edited on 2007-08-21 10:35:05.0
|
fixed bug in bug fix... see r12605
new implementation of mapOver:
/** Map this function over given list of symbols */
def mapOver(origSyms: List[Symbol]): List[Symbol] = {
val origInfos = origSyms map (_.info)
val newInfos = List.mapConserve(origInfos)(this)
if (newInfos eq origInfos) origSyms // fast path in case nothing changes due to map
else { // map is not the identity --> do cloning properly
val clonedSyms = origSyms map (_.cloneSymbol)
val clonedInfos = clonedSyms map (_.info.substSym(origSyms, clonedSyms))
val transformedInfos = List.mapConserve(clonedInfos)(this)
List.map2(clonedSyms, transformedInfos) {
((newSym, newInfo) => newSym.setInfo(newInfo))
}
clonedSyms
}
}
|
Adriaan edited on 2007-08-22 15:20:34.0
|
fixed in r12605
|