diff options
author | Martin Odersky <odersky@gmail.com> | 2008-09-04 16:33:51 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2008-09-04 16:33:51 +0000 |
commit | 3e0cd7e7488477e60eb8d12ffeea1b3dc02433a5 (patch) | |
tree | 39e044e9c789277e68c89a72533088dc4190e8d7 /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | 743edeefd44939ada6e81c5936cc04f7c6601931 (diff) | |
download | scala-3e0cd7e7488477e60eb8d12ffeea1b3dc02433a5.tar.gz scala-3e0cd7e7488477e60eb8d12ffeea1b3dc02433a5.tar.bz2 scala-3e0cd7e7488477e60eb8d12ffeea1b3dc02433a5.zip |
now checking for volatile types.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 529ec0444c..406e056128 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -253,7 +253,32 @@ trait Typers { self: Analyzer => */ def checkStable(tree: Tree): Tree = if (treeInfo.isPureExpr(tree)) tree - else errorTree(tree, "stable identifier required, but " + tree + " found.") + else errorTree( + tree, + "stable identifier required, but "+tree+" found."+ + (if (isStableExceptVolatile(tree)) { + val tpe = tree.symbol.tpe match { + case PolyType(_, rtpe) => rtpe + case t => t + } + "\n Note that "+tree.symbol+" is not stable because its type, "+tree.tpe+", is volatile." + } else "")) + + /** Would tree be a stable (i.e. a pure expression) if the type + * of its symbol was not volatile? + */ + private def isStableExceptVolatile(tree: Tree) = { + tree.hasSymbol && tree.symbol != NoSymbol && tree.tpe.isVolatile && + { val savedTpe = tree.symbol.info + val savedSTABLE = tree.symbol getFlag STABLE + tree.symbol setInfo AnyRefClass.tpe + tree.symbol setFlag STABLE + val result = treeInfo.isPureExpr(tree) + tree.symbol setInfo savedTpe + tree.symbol setFlag savedSTABLE + result + } + } /** Check that `tpt' refers to a non-refinement class type */ def checkClassType(tpt: Tree, existentialOK: Boolean) { @@ -671,7 +696,9 @@ trait Typers { self: Analyzer => (pt <:< functionType(mt.paramTypes map (t => WildcardType), WildcardType)))*/ { // (4.2) if (settings.debug.value) log("eta-expanding "+tree+":"+tree.tpe+" to "+pt) checkParamsConvertible(tree.pos, tree.tpe) - typed(etaExpand(context.unit, tree), mode, pt) + val tree1 = etaExpand(context.unit, tree) +// println("eta "+tree+" ---> "+tree1+":"+tree1.tpe) + typed(tree1, mode, pt) } else if (!meth.isConstructor && mt.paramTypes.isEmpty) { // (4.3) adapt(typed(Apply(tree, List()) setPos tree.pos), mode, pt) } else if (context.implicitsEnabled) { @@ -2430,17 +2457,18 @@ trait Typers { self: Analyzer => .setOriginal(tpt1) /* .setPos(tpt1.pos) */ .setType(appliedType(tpt1.tpe, context.undetparams map (_.tpe))) } + /** If current tree <tree> appears in <val x(: T)? = <tree>> + * return `tp with x.type' else return `tp'. + */ def narrowRhs(tp: Type) = { var sym = context.tree.symbol if (sym != null && sym != NoSymbol && sym.owner.isClass && sym.getter(sym.owner) != NoSymbol) sym = sym.getter(sym.owner) context.tree match { - case ValDef(_, _, _, Apply(Select(`tree`, _), _)) if (sym.isStable) => -// println("narrowing...") + case ValDef(mods, _, _, Apply(Select(`tree`, _), _)) if !(mods hasFlag MUTABLE) => val pre = if (sym.owner.isClass) sym.owner.thisType else NoPrefix intersectionType(List(tp, singleType(pre, sym))) case _ => -// println("no narrow: "+sym+" "+sym.isStable+" "+context.tree+"//"+tree) tp } } |