diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala | 5 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 21 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 3 | ||||
-rw-r--r-- | test/files/pos/bug602.scala | 11 | ||||
-rw-r--r-- | test/files/run/bug601.scala | 8 | ||||
-rw-r--r-- | test/files/run/bug603.scala | 33 |
7 files changed, 74 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index cc886f6e79..bbc476889b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -950,7 +950,9 @@ trait Types requires SymbolTable { case class TypeVar(origin: Type, constr: TypeConstraint) extends Type { override def symbol = origin.symbol override def toString(): String = - if (constr.inst eq NoType) "?" + origin else constr.inst.toString(); + if (constr.inst == null) "<null "+origin+">" + else if (constr.inst eq NoType) "?" + origin + else constr.inst.toString(); } /** A class representing an as-yet unevaluated type. diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala index 4524157ce5..cf90c4dda3 100644 --- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala +++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala @@ -333,11 +333,12 @@ abstract class ExplicitOuter extends InfoTransform { sym.makeNotPrivate(sym.owner); //(2) tree1 case Select(qual, name) => - if (currentOwner.enclClass != sym.owner) // (3) + val enclClass = currentOwner.enclClass + if (enclClass != sym.owner && enclClass != sym.moduleClass) // (3) sym.makeNotPrivate(sym.owner); if ((sym hasFlag PROTECTED) && //(4) !(qual.isInstanceOf[Super] || - (qual.tpe.widen.symbol isSubClass currentOwner.enclClass))) + (qual.tpe.widen.symbol isSubClass enclClass))) sym setFlag notPROTECTED; tree1 case _ => diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala index d2955bf9e5..3a87b7c25c 100644 --- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala +++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala @@ -73,6 +73,7 @@ abstract class UnCurry extends InfoTransform { private var inPattern = false; private var inConstructorFlag = 0L; private var localTyper: analyzer.Typer = analyzer.newTyper(analyzer.rootContext(unit)); + private var byNameArgs = new HashSet[Tree](16) override def transform(tree: Tree): Tree = try { //debug postTransform(mainTransform(tree)); @@ -86,10 +87,10 @@ abstract class UnCurry extends InfoTransform { * x.apply()? Note that this is not the case if `x' is used as an argument to another * call by name parameter. */ - def isByNameRef(tree: Tree): boolean = ( + def isByNameRef(tree: Tree): boolean = tree.isTerm && tree.hasSymbol && - tree.symbol.tpe.symbol == ByNameParamClass && tree.tpe == tree.symbol.tpe.typeArgs.head - ); + tree.symbol.tpe.symbol == ByNameParamClass && + !byNameArgs.contains(tree) /** Uncurry a type of a tree node. * This function is sensitive to whether or not we are in a pattern -- when in a pattern @@ -266,15 +267,19 @@ abstract class UnCurry extends InfoTransform { } case _ => args } - List.map2(formals, args1) ((formal, arg) => - if (formal.symbol != ByNameParamClass) arg - else if (isByNameRef(arg)) arg setType functionType(List(), arg.tpe) - else { + List.map2(formals, args1) { (formal, arg) => + if (formal.symbol != ByNameParamClass) { + arg + } else if (isByNameRef(arg)) { + byNameArgs.addEntry(arg) + arg setType functionType(List(), arg.tpe) + } else { val fun = localTyper.atOwner(currentOwner).typed( Function(List(), arg) setPos arg.pos).asInstanceOf[Function]; new ChangeOwnerTraverser(currentOwner, fun.symbol).traverse(arg); transformFunction(fun) - }) + } + } } } diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index a2c1da2bd4..4ba14aa147 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -96,6 +96,7 @@ trait Infer requires Analyzer { val up = if (variance != CONTRAVARIANT) upper else !upper; tvar.constr.inst = null; val bound: Type = if (up) tparam.info.bounds.hi else tparam.info.bounds.lo; + //Console.println("solveOne0 "+tvar+" "+config+" "+bound);//DEBUG var cyclic = false; for (val Pair(tvar2, Pair(tparam2, variance2)) <- config) { if (tparam2 != tparam && @@ -127,6 +128,8 @@ trait Infer requires Analyzer { tparam2.tpe.subst(tparams, tvars) :: tvar.constr.lobounds; } } + //Console.println("solveOne2 "+tvar+" "+config+" "+tvar.constr.hibounds);//DEBUG + tvar.constr.inst = NoType // necessary because hibounds/lobounds may contain tvar tvar.constr.inst = if (up) glb(tvar.constr.hibounds) else lub(tvar.constr.lobounds) } } diff --git a/test/files/pos/bug602.scala b/test/files/pos/bug602.scala new file mode 100644 index 0000000000..60aef1dfd0 --- /dev/null +++ b/test/files/pos/bug602.scala @@ -0,0 +1,11 @@ +package com.mosol.sl; + +case class Span[K <: Ordered[K]](low: Option[K], high: Option[K]) extends Function1[K, boolean] { + def apply(k: K): boolean = this match { + case Span(Some(low), Some(high)) => (k >= low && k <= high) + case Span(Some(low), None) => (k >= low) + case Span(None, Some(high)) => (k <= high) + case _ => false + } +} + diff --git a/test/files/run/bug601.scala b/test/files/run/bug601.scala new file mode 100644 index 0000000000..98b51ce97c --- /dev/null +++ b/test/files/run/bug601.scala @@ -0,0 +1,8 @@ +object Test +{ + private case object FooA + + def main(argv : Array[String]) : Unit = { + Console.println(FooA) + } +} diff --git a/test/files/run/bug603.scala b/test/files/run/bug603.scala new file mode 100644 index 0000000000..27cee562ce --- /dev/null +++ b/test/files/run/bug603.scala @@ -0,0 +1,33 @@ +object lazy { + class Susp[+A](lazyValue: => A) extends Function0[A] { + private var func: () => Any = () => lazyValue + private var value: Any = null + + override def apply() = { + if (func != null) { + value = func().asInstanceOf[A] + func = null + } + value.asInstanceOf[A] + } + + override def toString() = + if (func == null) "Susp(" + value + ")" + else "Susp(?)" + } + + def delay[A](value: => A) = new Susp[A](value) + implicit def force[A](s: Susp[A]): A = s() +} + +object lazy_test { + import lazy._ + + def main(args: Array[String]) = { + val s: Susp[Int] = delay { Console.println("evaluating..."); 3 } + Console.println("s = " + s) + Console.println("s() = " + s()) + Console.println("s = " + s) + Console.println("2 + s = " + (2 + s)) + } +} |