diff options
45 files changed, 376 insertions, 178 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index d8bf23f4fe..046b177444 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -879,7 +879,7 @@ abstract class ClassfileParser { case tpnme.ScalaSignatureATTR => if (!isScalaAnnot) { debuglog("warning: symbol " + sym.fullName + " has pickled signature in attribute") - unpickler.unpickle(in.buf, in.bp, clazz, staticModule, in.file.toString) + unpickler.unpickle(in.buf, in.bp, clazz, staticModule, in.file.name) } in.skip(attrLen) case tpnme.ScalaATTR => @@ -897,7 +897,7 @@ abstract class ClassfileParser { case Some(san: AnnotationInfo) => val bytes = san.assocs.find({ _._1 == nme.bytes }).get._2.asInstanceOf[ScalaSigBytes].bytes - unpickler.unpickle(bytes, 0, clazz, staticModule, in.file.toString) + unpickler.unpickle(bytes, 0, clazz, staticModule, in.file.name) case None => throw new RuntimeException("Scala class file does not contain Scala annotation") } @@ -1013,9 +1013,16 @@ abstract class ClassfileParser { } catch { case f: FatalError => throw f // don't eat fatal errors, they mean a class was not found case ex: Throwable => - debuglog("dropping annotation on " + sym + ", an error occured during parsing (e.g. annotation class not found)") - - None // ignore malformed annotations ==> t1135 + // We want to be robust when annotations are unavailable, so the very least + // we can do is warn the user about the exception + // There was a reference to ticket 1135, but that is outdated: a reference to a class not on + // the classpath would *not* end up here. A class not found is signaled + // with a `FatalError` exception, handled above. Here you'd end up after a NPE (for example), + // and that should never be swallowed silently. + warning("Caught: " + ex + " while parsing annotations in " + in.file) + if (settings.debug.value) ex.printStackTrace() + + None // ignore malformed annotations } /** diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 1d820afe11..124d350385 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -1355,8 +1355,19 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } } } + + def reportError[T](body: =>T)(handler: TypeError => T): T = + try body + catch { + case te: TypeError => + reporter.error(te.pos, te.msg) + handler(te) + } - override def transform(tree: Tree): Tree = { + override def transform(tree: Tree): Tree = + reportError { transform1(tree) } {_ => tree} + + def transform1(tree: Tree) = { val symbol = tree.symbol /** The specialized symbol of 'tree.symbol' for tree.tpe, if there is one */ @@ -1382,14 +1393,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { } else None } - def reportError[T](body: =>T)(handler: TypeError => T): T = - try body - catch { - case te: TypeError => - reporter.error(tree.pos, te.msg) - handler(te) - } - curTree = tree tree match { case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => @@ -1501,13 +1504,8 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case ddef @ DefDef(_, _, _, vparamss, _, _) if info.isDefinedAt(symbol) => // log("--> method: " + ddef + " in " + ddef.symbol.owner + ", " + info(symbol)) - def reportTypeError(body: =>Tree) = - try body - catch { - case te: TypeError => - reporter.error(te.pos, te.toString) - ddef - } + def reportTypeError(body: =>Tree) = reportError(body)(_ => ddef) + if (symbol.isConstructor) { val t = atOwner(symbol)(forwardCtorCall(tree.pos, gen.mkSuperSelect, vparamss, symbol.owner)) diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 688dcd91ac..e99c31374e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -1104,7 +1104,9 @@ trait Infer { try { // debuglog("TVARS "+ (tvars map (_.constr))) // look at the argument types of the primary constructor corresponding to the pattern - val variances = undetparams map varianceInType(ctorTp.paramTypes.headOption getOrElse ctorTp) + val variances = + if (ctorTp.paramTypes.isEmpty) undetparams map varianceInType(ctorTp) + else undetparams map varianceInTypes(ctorTp.paramTypes) val targs = solvedTypes(tvars, undetparams, variances, true, lubDepth(List(resTp, pt))) // checkBounds(tree, NoPrefix, NoSymbol, undetparams, targs, "inferred ") // no checkBounds here. If we enable it, test bug602 fails. diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala index f99d0e733b..c466206192 100644 --- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala +++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala @@ -123,7 +123,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL def zero: M[Nothing] def one[T](x: P[T]): M[T] def guard[T](cond: P[Boolean], then: => P[T]): M[T] - def isSuccess[T, U](x: P[T])(f: P[T] => M[U]): P[Boolean] // used for isDefinedAt } * P and M are derived from one's signature (`def one[T](x: P[T]): M[T]`) @@ -137,7 +136,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // NOTE: guard's return type must be of the shape M[T], where M is the monad in which the pattern match should be interpreted def guard[T](cond: Boolean, then: => T): Option[T] = if(cond) Some(then) else None def runOrElse[T, U](x: T)(f: T => Option[U]): U = f(x) getOrElse (throw new MatchError(x)) - def isSuccess[T, U](x: T)(f: T => Option[U]): Boolean = !f(x).isEmpty } */ @@ -2006,7 +2004,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL private val uniques = new collection.mutable.HashMap[Tree, Var] def apply(x: Tree): Var = uniques getOrElseUpdate(x, new Var(x, x.tpe)) } - class Var(val path: Tree, fullTp: Type, checked: Boolean = true) extends AbsVar { + class Var(val path: Tree, fullTp: Type) extends AbsVar { private[this] val id: Int = Var.nextId // private[this] var canModify: Option[Array[StackTraceElement]] = None @@ -2028,26 +2026,24 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // we enumerate the subtypes of the full type, as that allows us to filter out more types statically, // once we go to run-time checks (on Const's), convert them to checkable types // TODO: there seems to be bug for singleton domains (variable does not show up in model) - lazy val domain: Option[Set[Const]] = - if (!checked) None - else { - val subConsts = enumerateSubtypes(fullTp).map{ tps => - tps.toSet[Type].map{ tp => - val domainC = TypeConst(tp) - registerEquality(domainC) - domainC - } + lazy val domain: Option[Set[Const]] = { + val subConsts = enumerateSubtypes(fullTp).map{ tps => + tps.toSet[Type].map{ tp => + val domainC = TypeConst(tp) + registerEquality(domainC) + domainC } + } - val allConsts = - if (! _considerNull) subConsts - else { - registerEquality(NullConst) - subConsts map (_ + NullConst) - } + val allConsts = + if (! _considerNull) subConsts + else { + registerEquality(NullConst) + subConsts map (_ + NullConst) + } - observed; allConsts - } + observed; allConsts + } // accessing after calling considerNull will result in inconsistencies lazy val domainSyms: Option[Set[Sym]] = domain map { _ map symForEqualsTo } @@ -2157,6 +2153,21 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // the equals inherited from AnyRef does just this } + // find most precise super-type of tp that is a class + // we skip non-class types (singleton types, abstract types) so that we can + // correctly compute how types relate in terms of the values they rule out + // e.g., when we know some value must be of type T, can it still be of type S? (this is the positive formulation of what `excludes` on Const computes) + // since we're talking values, there must have been a class involved in creating it, so rephrase our types in terms of classes + // (At least conceptually: `true` is an instance of class `Boolean`) + private def widenToClass(tp: Type) = { + // getOrElse to err on the safe side -- all BTS should end in Any, right? + val wideTp = tp.widen + val clsTp = + if (wideTp.typeSymbol.isClass) wideTp + else wideTp.baseTypeSeq.toList.find(_.typeSymbol.isClass).getOrElse(AnyClass.tpe) + // patmatDebug("Widening to class: "+ (tp, clsTp, tp.widen, tp.widen.baseTypeSeq, tp.widen.baseTypeSeq.toList.find(_.typeSymbol.isClass))) + clsTp + } object TypeConst { def apply(tp: Type) = { @@ -2172,7 +2183,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL assert(!(tp =:= NullTp)) private[this] val id: Int = Const.nextTypeId - val wideTp = tp.widen + val wideTp = widenToClass(tp) override def toString = tp.toString //+"#"+ id } @@ -2191,10 +2202,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL val tp = p.tpe.normalize if (tp =:= NullTp) NullConst else { - val wideTp = { - if (p.hasSymbol && p.symbol.isStable) tp.asSeenFrom(tp.prefix, p.symbol.owner).widen - else tp.widen - } + val wideTp = widenToClass(tp) val narrowTp = if (tp.isInstanceOf[SingletonType]) tp @@ -2354,16 +2362,19 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL // exhaustivity - // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte - // TODO: domain of feasibly enumerable built-in types (enums, char?) + // TODO: domain of other feasibly enumerable built-in types (char?) def enumerateSubtypes(tp: Type): Option[List[Type]] = tp.typeSymbol match { + // TODO case _ if tp.isTupleType => // recurse into component types? + case UnitClass => + Some(List(UnitClass.tpe)) case BooleanClass => // patmatDebug("enum bool "+ tp) Some(List(ConstantType(Constant(true)), ConstantType(Constant(false)))) // TODO case _ if tp.isTupleType => // recurse into component types case modSym: ModuleClassSymbol => Some(List(tp)) + // make sure it's not a primitive, else (5: Byte) match { case 5 => ... } sees no Byte case sym if !sym.isSealed || isPrimitiveValueClass(sym) => // patmatDebug("enum unsealed "+ (tp, sym, sym.isSealed, isPrimitiveValueClass(sym))) None diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index e6186bd41a..d251109dc4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -3103,66 +3103,67 @@ trait Typers extends Modes with Adaptations with Tags { val otpe = fun.tpe - if (args.length > MaxTupleArity) - return duplErrorTree(TooManyArgsPatternError(fun)) - - // - def freshArgType(tp: Type): (List[Symbol], Type) = tp match { - case MethodType(param :: _, _) => - (Nil, param.tpe) - case PolyType(tparams, restpe) => - createFromClonedSymbols(tparams, freshArgType(restpe)._2)((ps, t) => ((ps, t))) - // No longer used, see test case neg/t960.scala (#960 has nothing to do with it) - case OverloadedType(_, _) => - OverloadedUnapplyError(fun) - (Nil, ErrorType) - case _ => - UnapplyWithSingleArgError(fun) - (Nil, ErrorType) - } + if (args.length > MaxTupleArity) + return duplErrorTree(TooManyArgsPatternError(fun)) + + // + def freshArgType(tp: Type): (List[Symbol], Type) = tp match { + case MethodType(param :: _, _) => + (Nil, param.tpe) + case PolyType(tparams, restpe) => + createFromClonedSymbols(tparams, freshArgType(restpe)._2)((ps, t) => ((ps, t))) + // No longer used, see test case neg/t960.scala (#960 has nothing to do with it) + case OverloadedType(_, _) => + OverloadedUnapplyError(fun) + (Nil, ErrorType) + case _ => + UnapplyWithSingleArgError(fun) + (Nil, ErrorType) + } - val unapp = unapplyMember(otpe) - val unappType = otpe.memberType(unapp) - val argDummy = context.owner.newValue(nme.SELECTOR_DUMMY, fun.pos, SYNTHETIC) setInfo pt - val arg = Ident(argDummy) setType pt + val unapp = unapplyMember(otpe) + val unappType = otpe.memberType(unapp) + val argDummy = context.owner.newValue(nme.SELECTOR_DUMMY, fun.pos, SYNTHETIC) setInfo pt + val arg = Ident(argDummy) setType pt val uncheckedTypeExtractor = if (unappType.paramTypes.nonEmpty) extractorForUncheckedType(tree.pos, unappType.paramTypes.head) else None - if (!isApplicableSafe(Nil, unappType, List(pt), WildcardType)) { - //Console.println("UNAPP: need to typetest, arg.tpe = "+arg.tpe+", unappType = "+unappType) - val (freeVars, unappFormal) = freshArgType(unappType.skolemizeExistential(context.owner, tree)) - val unapplyContext = context.makeNewScope(context.tree, context.owner) - freeVars foreach unapplyContext.scope.enter + if (!isApplicableSafe(Nil, unappType, List(pt), WildcardType)) { + //Console.println("UNAPP: need to typetest, arg.tpe = "+arg.tpe+", unappType = "+unappType) + val (freeVars, unappFormal) = freshArgType(unappType.skolemizeExistential(context.owner, tree)) + val unapplyContext = context.makeNewScope(context.tree, context.owner) + freeVars foreach unapplyContext.scope.enter - val typer1 = newTyper(unapplyContext) + val typer1 = newTyper(unapplyContext) val pattp = typer1.infer.inferTypedPattern(tree, unappFormal, arg.tpe, canRemedy = uncheckedTypeExtractor.nonEmpty) - // turn any unresolved type variables in freevars into existential skolems - val skolems = freeVars map (fv => unapplyContext.owner.newExistentialSkolem(fv, fv)) - arg.tpe = pattp.substSym(freeVars, skolems) - argDummy setInfo arg.tpe - } + // turn any unresolved type variables in freevars into existential skolems + val skolems = freeVars map (fv => unapplyContext.owner.newExistentialSkolem(fv, fv)) + arg.tpe = pattp.substSym(freeVars, skolems) + argDummy setInfo arg.tpe + } - // setType null is necessary so that ref will be stabilized; see bug 881 - val fun1 = typedPos(fun.pos)(Apply(Select(fun setType null, unapp), List(arg))) + // setType null is necessary so that ref will be stabilized; see bug 881 + val fun1 = typedPos(fun.pos)(Apply(Select(fun setType null, unapp), List(arg))) - if (fun1.tpe.isErroneous) { - duplErrTree - } else { - val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe) - val formals1 = formalTypes(formals0, args.length) - if (sameLength(formals1, args)) { - val args1 = typedArgs(args, mode, formals0, formals1) - // This used to be the following (failing) assert: - // assert(isFullyDefined(pt), tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt) - // I modified as follows. See SI-1048. - val pt1 = if (isFullyDefined(pt)) pt else makeFullyDefined(pt) - - val itype = glb(List(pt1, arg.tpe)) - arg.tpe = pt1 // restore type (arg is a dummy tree, just needs to pass typechecking) + if (fun1.tpe.isErroneous) duplErrTree + else { + val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe) + val formals1 = formalTypes(formals0, args.length) + + if (!sameLength(formals1, args)) duplErrorTree(WrongNumberArgsPatternError(tree, fun)) + else { + val args1 = typedArgs(args, mode, formals0, formals1) + // This used to be the following (failing) assert: + // assert(isFullyDefined(pt), tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt) + // I modified as follows. See SI-1048. + val pt1 = if (isFullyDefined(pt)) pt else makeFullyDefined(pt) + + val itype = glb(List(pt1, arg.tpe)) + arg.tpe = pt1 // restore type (arg is a dummy tree, just needs to pass typechecking) val unapply = UnApply(fun1, args1) setPos tree.pos setType itype // if the type that the unapply method expects for its argument is uncheckable, wrap in classtag extractor @@ -3170,9 +3171,8 @@ trait Typers extends Modes with Adaptations with Tags { // also skip if we already wrapped a classtag extractor (so we don't keep doing that forever) if (uncheckedTypeExtractor.isEmpty || fun1.symbol.owner.isNonBottomSubClass(ClassTagClass)) unapply else wrapClassTagUnapply(unapply, uncheckedTypeExtractor.get, unappType.paramTypes.head) - } else - duplErrorTree(WrongNumberArgsPatternError(tree, fun)) - } + } + } } def wrapClassTagUnapply(uncheckedPattern: Tree, classTagExtractor: Tree, pt: Type): Tree = { @@ -4977,7 +4977,7 @@ trait Typers extends Modes with Adaptations with Tags { typedTypeApply(tree, mode, fun1, args1) case Apply(Block(stats, expr), args) => - typed1(atPos(tree.pos)(Block(stats, Apply(expr, args))), mode, pt) + typed1(atPos(tree.pos)(Block(stats, Apply(expr, args) setPos tree.pos.makeTransparent)), mode, pt) case Apply(fun, args) => typedApply(fun, args) match { diff --git a/src/library/scala/collection/IterableViewLike.scala b/src/library/scala/collection/IterableViewLike.scala index c842475590..e0c8b21d09 100644 --- a/src/library/scala/collection/IterableViewLike.scala +++ b/src/library/scala/collection/IterableViewLike.scala @@ -44,7 +44,7 @@ trait IterableViewLike[+A, } /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ - private[collection] abstract class AbstractTransformed[+B] extends super[TraversableViewLike].Transformed[B] with Transformed[B] + private[collection] abstract class AbstractTransformed[+B] extends Iterable[B] with super[TraversableViewLike].Transformed[B] with Transformed[B] trait EmptyView extends Transformed[Nothing] with super[TraversableViewLike].EmptyView with super[GenIterableViewLike].EmptyView diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala index f64045c9f6..73f5dda11c 100644 --- a/src/library/scala/collection/SeqViewLike.scala +++ b/src/library/scala/collection/SeqViewLike.scala @@ -40,7 +40,7 @@ trait SeqViewLike[+A, } /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ - private[collection] abstract class AbstractTransformed[+B] extends super[IterableViewLike].AbstractTransformed[B] with Transformed[B] + private[collection] abstract class AbstractTransformed[+B] extends Seq[B] with super[IterableViewLike].Transformed[B] with Transformed[B] trait EmptyView extends Transformed[Nothing] with super[IterableViewLike].EmptyView with super[GenSeqViewLike].EmptyView diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala index eb2091a5f3..bf4f8205d6 100644 --- a/src/library/scala/collection/TraversableViewLike.scala +++ b/src/library/scala/collection/TraversableViewLike.scala @@ -117,7 +117,7 @@ trait TraversableViewLike[+A, } /** Explicit instantiation of the `Transformed` trait to reduce class file size in subclasses. */ - private[collection] abstract class AbstractTransformed[+B] extends Transformed[B] + private[collection] abstract class AbstractTransformed[+B] extends Traversable[B] with Transformed[B] trait EmptyView extends Transformed[Nothing] with super.EmptyView diff --git a/src/library/scala/collection/immutable/RedBlackTree.scala b/src/library/scala/collection/immutable/RedBlackTree.scala index 0f28c4997b..4b573511d1 100644 --- a/src/library/scala/collection/immutable/RedBlackTree.scala +++ b/src/library/scala/collection/immutable/RedBlackTree.scala @@ -43,7 +43,7 @@ object RedBlackTree { } def count(tree: Tree[_, _]) = if (tree eq null) 0 else tree.count - def update[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1)(implicit ordering: Ordering[A]): Tree[A, B1] = blacken(upd(tree, k, v)) + def update[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = blacken(upd(tree, k, v, overwrite)) def delete[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = blacken(del(tree, k)) def rangeImpl[A: Ordering, B](tree: Tree[A, B], from: Option[A], until: Option[A]): Tree[A, B] = (from, until) match { case (Some(from), Some(until)) => this.range(tree, from, until) @@ -122,17 +122,18 @@ object RedBlackTree { else mkTree(isBlack, x, xv, a, r) } - private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { + private[this] def upd[A, B, B1 >: B](tree: Tree[A, B], k: A, v: B1, overwrite: Boolean)(implicit ordering: Ordering[A]): Tree[A, B1] = if (tree eq null) { RedTree(k, v, null, null) } else { val cmp = ordering.compare(k, tree.key) - if (cmp < 0) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v), tree.right) - else if (cmp > 0) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v)) - else mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + if (cmp < 0) balanceLeft(isBlackTree(tree), tree.key, tree.value, upd(tree.left, k, v, overwrite), tree.right) + else if (cmp > 0) balanceRight(isBlackTree(tree), tree.key, tree.value, tree.left, upd(tree.right, k, v, overwrite)) + else if (overwrite || k != tree.key) mkTree(isBlackTree(tree), k, v, tree.left, tree.right) + else tree } - // Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees - // http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html + /* Based on Stefan Kahrs' Haskell version of Okasaki's Red&Black Trees + * http://www.cse.unsw.edu.au/~dons/data/RedBlackTree.html */ private[this] def del[A, B](tree: Tree[A, B], k: A)(implicit ordering: Ordering[A]): Tree[A, B] = if (tree eq null) null else { def balance(x: A, xv: B, tl: Tree[A, B], tr: Tree[A, B]) = if (isRedTree(tl)) { if (isRedTree(tr)) { @@ -216,7 +217,7 @@ object RedBlackTree { if (ordering.lt(tree.key, from)) return doFrom(tree.right, from) val newLeft = doFrom(tree.left, from) if (newLeft eq tree.left) tree - else if (newLeft eq null) upd(tree.right, tree.key, tree.value) + else if (newLeft eq null) upd(tree.right, tree.key, tree.value, false) else rebalance(tree, newLeft, tree.right) } private[this] def doTo[A, B](tree: Tree[A, B], to: A)(implicit ordering: Ordering[A]): Tree[A, B] = { @@ -224,7 +225,7 @@ object RedBlackTree { if (ordering.lt(to, tree.key)) return doTo(tree.left, to) val newRight = doTo(tree.right, to) if (newRight eq tree.right) tree - else if (newRight eq null) upd(tree.left, tree.key, tree.value) + else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) else rebalance(tree, tree.left, newRight) } private[this] def doUntil[A, B](tree: Tree[A, B], until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { @@ -232,7 +233,7 @@ object RedBlackTree { if (ordering.lteq(until, tree.key)) return doUntil(tree.left, until) val newRight = doUntil(tree.right, until) if (newRight eq tree.right) tree - else if (newRight eq null) upd(tree.left, tree.key, tree.value) + else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) else rebalance(tree, tree.left, newRight) } private[this] def doRange[A, B](tree: Tree[A, B], from: A, until: A)(implicit ordering: Ordering[A]): Tree[A, B] = { @@ -242,8 +243,8 @@ object RedBlackTree { val newLeft = doFrom(tree.left, from) val newRight = doUntil(tree.right, until) if ((newLeft eq tree.left) && (newRight eq tree.right)) tree - else if (newLeft eq null) upd(newRight, tree.key, tree.value); - else if (newRight eq null) upd(newLeft, tree.key, tree.value); + else if (newLeft eq null) upd(newRight, tree.key, tree.value, false); + else if (newRight eq null) upd(newLeft, tree.key, tree.value, false); else rebalance(tree, newLeft, newRight) } @@ -254,7 +255,7 @@ object RedBlackTree { if (n > count) return doDrop(tree.right, n - count - 1) val newLeft = doDrop(tree.left, n) if (newLeft eq tree.left) tree - else if (newLeft eq null) upd(tree.right, tree.key, tree.value) + else if (newLeft eq null) upd(tree.right, tree.key, tree.value, false) else rebalance(tree, newLeft, tree.right) } private[this] def doTake[A: Ordering, B](tree: Tree[A, B], n: Int): Tree[A, B] = { @@ -264,7 +265,7 @@ object RedBlackTree { if (n <= count) return doTake(tree.left, n) val newRight = doTake(tree.right, n - count - 1) if (newRight eq tree.right) tree - else if (newRight eq null) upd(tree.left, tree.key, tree.value) + else if (newRight eq null) upd(tree.left, tree.key, tree.value, false) else rebalance(tree, tree.left, newRight) } private[this] def doSlice[A: Ordering, B](tree: Tree[A, B], from: Int, until: Int): Tree[A, B] = { @@ -275,8 +276,8 @@ object RedBlackTree { val newLeft = doDrop(tree.left, from) val newRight = doTake(tree.right, until - count - 1) if ((newLeft eq tree.left) && (newRight eq tree.right)) tree - else if (newLeft eq null) upd(newRight, tree.key, tree.value) - else if (newRight eq null) upd(newLeft, tree.key, tree.value) + else if (newLeft eq null) upd(newRight, tree.key, tree.value, false) + else if (newRight eq null) upd(newLeft, tree.key, tree.value, false) else rebalance(tree, newLeft, newRight) } diff --git a/src/library/scala/collection/immutable/TreeMap.scala b/src/library/scala/collection/immutable/TreeMap.scala index 4c1a5f2e03..51bc76efc3 100644 --- a/src/library/scala/collection/immutable/TreeMap.scala +++ b/src/library/scala/collection/immutable/TreeMap.scala @@ -131,7 +131,7 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi * @param value the value to be associated with `key` * @return a new $coll with the updated binding */ - override def updated [B1 >: B](key: A, value: B1): TreeMap[A, B1] = new TreeMap(RB.update(tree, key, value)) + override def updated [B1 >: B](key: A, value: B1): TreeMap[A, B1] = new TreeMap(RB.update(tree, key, value, true)) /** Add a key/value pair to this map. * @tparam B1 type of the value of the new binding, a supertype of `B` @@ -171,7 +171,7 @@ class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering: Orderi */ def insert [B1 >: B](key: A, value: B1): TreeMap[A, B1] = { assert(!RB.contains(tree, key)) - new TreeMap(RB.update(tree, key, value)) + new TreeMap(RB.update(tree, key, value, true)) } def - (key:A): TreeMap[A, B] = diff --git a/src/library/scala/collection/immutable/TreeSet.scala b/src/library/scala/collection/immutable/TreeSet.scala index 882e828c5b..697da2bc4b 100644 --- a/src/library/scala/collection/immutable/TreeSet.scala +++ b/src/library/scala/collection/immutable/TreeSet.scala @@ -112,7 +112,7 @@ class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Orderin * @param elem a new element to add. * @return a new $coll containing `elem` and all the elements of this $coll. */ - def + (elem: A): TreeSet[A] = newSet(RB.update(tree, elem, ())) + def + (elem: A): TreeSet[A] = newSet(RB.update(tree, elem, (), false)) /** A new `TreeSet` with the entry added is returned, * assuming that elem is <em>not</em> in the TreeSet. @@ -122,7 +122,7 @@ class TreeSet[A] private (tree: RB.Tree[A, Unit])(implicit val ordering: Orderin */ def insert(elem: A): TreeSet[A] = { assert(!RB.contains(tree, elem)) - newSet(RB.update(tree, elem, ())) + newSet(RB.update(tree, elem, (), false)) } /** Creates a new `TreeSet` with the entry removed. diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index a7ec833193..815253b537 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -841,7 +841,7 @@ self: ParIterableLike[T, Repr, Sequential] => override def toBuffer[U >: T]: collection.mutable.Buffer[U] = seq.toBuffer // have additional, parallel buffers? - override def toTraversable: GenTraversable[T] = this.asInstanceOf[GenTraversable[T]] // TODO add ParTraversable[T] + override def toTraversable: GenTraversable[T] = this.asInstanceOf[GenTraversable[T]] override def toIterable: ParIterable[T] = this.asInstanceOf[ParIterable[T]] @@ -850,13 +850,13 @@ self: ParIterableLike[T, Repr, Sequential] => override def toSet[U >: T]: immutable.ParSet[U] = toParCollection[U, immutable.ParSet[U]](() => immutable.ParSet.newCombiner[U]) override def toMap[K, V](implicit ev: T <:< (K, V)): immutable.ParMap[K, V] = toParMap[K, V, immutable.ParMap[K, V]](() => immutable.ParMap.newCombiner[K, V]) - - // TODO(@alex22): make these better - override def toVector: Vector[T] = seq.toVector - - override def convertTo[Col[_]](implicit cbf: CanBuildFrom[Nothing, T, Col[T @uncheckedVariance]]): Col[T @uncheckedVariance] = seq.convertTo[Col] + override def toVector: Vector[T] = convertTo[Vector] + override def convertTo[Col[_]](implicit cbf: CanBuildFrom[Nothing, T, Col[T @uncheckedVariance]]): Col[T @uncheckedVariance] = if (cbf().isCombiner) { + toParCollection[T, Col[T]](() => cbf().asCombiner) + } else seq.convertTo(cbf) + /* tasks */ protected trait StrictSplitterCheckTask[R, Tp] extends Task[R, Tp] { diff --git a/src/library/scala/collection/parallel/immutable/ParIterable.scala b/src/library/scala/collection/parallel/immutable/ParIterable.scala index d8c42d74b0..349f4fa44c 100644 --- a/src/library/scala/collection/parallel/immutable/ParIterable.scala +++ b/src/library/scala/collection/parallel/immutable/ParIterable.scala @@ -34,6 +34,7 @@ extends collection/*.immutable*/.GenIterable[T] with collection.parallel.ParIterable[T] with GenericParTemplate[T, ParIterable] with ParIterableLike[T, ParIterable[T], collection.immutable.Iterable[T]] + with Immutable { override def companion: GenericCompanion[ParIterable] with GenericParCompanion[ParIterable] = ParIterable diff --git a/src/library/scala/collection/parallel/mutable/ParIterable.scala b/src/library/scala/collection/parallel/mutable/ParIterable.scala index 700d21d0bb..b5747a31cf 100644 --- a/src/library/scala/collection/parallel/mutable/ParIterable.scala +++ b/src/library/scala/collection/parallel/mutable/ParIterable.scala @@ -29,7 +29,8 @@ import scala.collection.GenIterable trait ParIterable[T] extends collection/*.mutable*/.GenIterable[T] with collection.parallel.ParIterable[T] with GenericParTemplate[T, ParIterable] - with ParIterableLike[T, ParIterable[T], Iterable[T]] { + with ParIterableLike[T, ParIterable[T], Iterable[T]] + with Mutable { override def companion: GenericCompanion[ParIterable] with GenericParCompanion[ParIterable] = ParIterable //protected[this] override def newBuilder = ParIterable.newBuilder[T] diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index f753dfbcbb..860e7bac28 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -52,7 +52,7 @@ trait ClassTag[T] extends Equals with Serializable { * `SomeExtractor(...)` is turned into `ct(SomeExtractor(...))` if `T` in `SomeExtractor.unapply(x: T)` * is uncheckable, but we have an instance of `ClassTag[T]`. */ - def unapply(x: Any): Option[T] = if (runtimeClass.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[T]) else None + def unapply(x: Any): Option[T] = if (x != null && runtimeClass.isAssignableFrom(x.getClass)) Some(x.asInstanceOf[T]) else None /** case class accessories */ override def canEqual(x: Any) = x.isInstanceOf[ClassTag[_]] diff --git a/src/library/scala/reflect/compat.scala b/src/library/scala/reflect/compat.scala deleted file mode 100644 index fc0e5fbf9c..0000000000 --- a/src/library/scala/reflect/compat.scala +++ /dev/null @@ -1,33 +0,0 @@ -// [Eugene++] delete this once we merge with trunk and have a working IDE - -package scala.reflect { - trait ArrayTag[T] - trait ErasureTag[T] - trait ConcreteTypeTag[T] -} - -package scala.reflect.api { - trait TypeTags { - trait TypeTag[T] - trait ConcreteTypeTag[T] - } -} - -package scala { - import scala.reflect.base.{Universe => BaseUniverse} - - trait reflect_compat { - lazy val mirror: BaseUniverse = ??? - } -} - -package scala.reflect { - import language.experimental.macros - import scala.reflect.base.{Universe => BaseUniverse} - - trait internal_compat { - private[scala] def materializeArrayTag[T](u: BaseUniverse): ArrayTag[T] = ??? - private[scala] def materializeErasureTag[T](u: BaseUniverse): ErasureTag[T] = ??? - private[scala] def materializeConcreteTypeTag[T](u: BaseUniverse): ConcreteTypeTag[T] = ??? - } -}
\ No newline at end of file diff --git a/src/library/scala/reflect/makro/internal/package.scala b/src/library/scala/reflect/makro/internal/package.scala index d31a0f0d14..78cb0ffb10 100644 --- a/src/library/scala/reflect/makro/internal/package.scala +++ b/src/library/scala/reflect/makro/internal/package.scala @@ -9,7 +9,7 @@ import scala.reflect.base.{Universe => BaseUniverse} // // todo. once we have implicit macros for tag generation, we can remove these anchors // [Eugene++] how do I hide this from scaladoc? -package object internal extends scala.reflect.internal_compat { +package object internal { private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = macro ??? private[scala] def materializeAbsTypeTag[T](u: BaseUniverse): u.AbsTypeTag[T] = macro ??? private[scala] def materializeTypeTag[T](u: BaseUniverse): u.TypeTag[T] = macro ??? diff --git a/src/library/scala/reflect/package.scala b/src/library/scala/reflect/package.scala index 0ee58df2cd..2ebc82875e 100644 --- a/src/library/scala/reflect/package.scala +++ b/src/library/scala/reflect/package.scala @@ -1,6 +1,6 @@ package scala -package object reflect extends reflect_compat { +package object reflect { lazy val basis: base.Universe = new base.Base diff --git a/test/files/neg/macro-invalidret-nonuniversetree.check b/test/files/neg/macro-invalidret-nonuniversetree.check index 4fc06b5ceb..1b9487982f 100644 --- a/test/files/neg/macro-invalidret-nonuniversetree.check +++ b/test/files/neg/macro-invalidret-nonuniversetree.check @@ -1,7 +1,7 @@ Macros_Test_2.scala:2: error: macro implementation has wrong shape:
required: (c: scala.reflect.makro.Context): c.Expr[Any]
- found : (c: scala.reflect.makro.Context): reflect.mirror.Literal
-type mismatch for return type: reflect.mirror.Literal does not conform to c.Expr[Any]
+ found : (c: scala.reflect.makro.Context): reflect.basis.Literal
+type mismatch for return type: reflect.basis.Literal does not conform to c.Expr[Any]
def foo = macro Impls.foo
^
one error found
diff --git a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala index 86b7c8d8d0..da0eb0ac83 100644 --- a/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala +++ b/test/files/neg/macro-invalidret-nonuniversetree/Impls_1.scala @@ -1,5 +1,5 @@ import scala.reflect.makro.{Context => Ctx} object Impls { - def foo(c: Ctx) = scala.reflect.mirror.Literal(scala.reflect.mirror.Constant(42)) + def foo(c: Ctx) = scala.reflect.basis.Literal(scala.reflect.basis.Constant(42)) } diff --git a/test/files/neg/t2442.check b/test/files/neg/t2442.check new file mode 100644 index 0000000000..714816fd62 --- /dev/null +++ b/test/files/neg/t2442.check @@ -0,0 +1,9 @@ +t2442.scala:4: error: match may not be exhaustive. +It would fail on the following input: THREE + def f(e: MyEnum) = e match { + ^ +t2442.scala:11: error: match may not be exhaustive. +It would fail on the following input: BLUE + def g(e: MySecondEnum) = e match { + ^ +two errors found diff --git a/test/files/neg/t2442.flags b/test/files/neg/t2442.flags new file mode 100644 index 0000000000..32cf036c3d --- /dev/null +++ b/test/files/neg/t2442.flags @@ -0,0 +1 @@ +-Xexperimental -Xfatal-warnings
\ No newline at end of file diff --git a/test/files/neg/t2442/MyEnum.java b/test/files/neg/t2442/MyEnum.java new file mode 100644 index 0000000000..3ffbbb31b8 --- /dev/null +++ b/test/files/neg/t2442/MyEnum.java @@ -0,0 +1,3 @@ +public enum MyEnum { + ONE, TWO, THREE; +}
\ No newline at end of file diff --git a/test/files/neg/t2442/MySecondEnum.java b/test/files/neg/t2442/MySecondEnum.java new file mode 100644 index 0000000000..0f841286de --- /dev/null +++ b/test/files/neg/t2442/MySecondEnum.java @@ -0,0 +1,6 @@ +public enum MySecondEnum { + RED(1), BLUE(2) { public void foo() {} }; + MySecondEnum(int i) {} + + public void foo() {} +}
\ No newline at end of file diff --git a/test/files/neg/t2442/t2442.scala b/test/files/neg/t2442/t2442.scala new file mode 100644 index 0000000000..b0a0f3cd41 --- /dev/null +++ b/test/files/neg/t2442/t2442.scala @@ -0,0 +1,15 @@ +class Test { + import MyEnum._ + + def f(e: MyEnum) = e match { + case ONE => println("one") + case TWO => println("two") + // missing case --> exhaustivity warning! + } + + import MySecondEnum._ + def g(e: MySecondEnum) = e match { + case RED => println("red") + // missing case --> exhaustivity warning! + } +}
\ No newline at end of file diff --git a/test/files/neg/t4541.check b/test/files/neg/t4541.check index c01226685f..7bd8ff78f9 100644 --- a/test/files/neg/t4541.check +++ b/test/files/neg/t4541.check @@ -1,7 +1,7 @@ -t4541.scala:11: error: scala.reflect.internal.Types$TypeError: variable data in class Sparse cannot be accessed in Sparse[Int] +t4541.scala:11: error: variable data in class Sparse cannot be accessed in Sparse[Int] Access to protected method data not permitted because prefix type Sparse[Int] does not conform to class Sparse$mcI$sp where the access take place that.data ^ -one error found
\ No newline at end of file +one error found diff --git a/test/files/neg/t4541b.check b/test/files/neg/t4541b.check index 54d9c3d1ee..8a52fd97f4 100644 --- a/test/files/neg/t4541b.check +++ b/test/files/neg/t4541b.check @@ -1,7 +1,7 @@ -t4541b.scala:13: error: scala.reflect.internal.Types$TypeError: variable data in class SparseArray cannot be accessed in SparseArray[Int] +t4541b.scala:13: error: variable data in class SparseArray cannot be accessed in SparseArray[Int] Access to protected method data not permitted because prefix type SparseArray[Int] does not conform to class SparseArray$mcI$sp where the access take place use(that.data.clone) ^ -one error found
\ No newline at end of file +one error found diff --git a/test/files/neg/t5148.check b/test/files/neg/t5148.check new file mode 100644 index 0000000000..96eb1fd364 --- /dev/null +++ b/test/files/neg/t5148.check @@ -0,0 +1,2 @@ +error: bad reference while unpickling Imports.class: term memberHandlers not found in scala.tools.nsc.interpreter.IMain +one error found diff --git a/test/files/neg/t5148.scala b/test/files/neg/t5148.scala new file mode 100644 index 0000000000..fca64e57df --- /dev/null +++ b/test/files/neg/t5148.scala @@ -0,0 +1,4 @@ +package scala.tools.nsc +package interpreter + +class IMain extends Imports diff --git a/test/files/neg/t5839.check b/test/files/neg/t5839.check new file mode 100644 index 0000000000..d4b125bd1e --- /dev/null +++ b/test/files/neg/t5839.check @@ -0,0 +1,6 @@ +t5839.scala:5: error: type mismatch; + found : (x: String => String)Int <and> (x: Int)Int + required: Int => String + val x: String = goo(foo _) + ^ +one error found diff --git a/test/files/neg/t5839.scala b/test/files/neg/t5839.scala new file mode 100644 index 0000000000..d3a5d4b25f --- /dev/null +++ b/test/files/neg/t5839.scala @@ -0,0 +1,7 @@ +object Test { + def goo[T](x: Int => T): T = x(1) + implicit def f(x: Int): String = "" + def foo(x: Int): Int = x + 1 + val x: String = goo(foo _) + def foo(x: String => String) = 1 +} diff --git a/test/files/pos/rangepos-anonapply.flags b/test/files/pos/rangepos-anonapply.flags new file mode 100644 index 0000000000..281f0a10cd --- /dev/null +++ b/test/files/pos/rangepos-anonapply.flags @@ -0,0 +1 @@ +-Yrangepos diff --git a/test/files/pos/rangepos-anonapply.scala b/test/files/pos/rangepos-anonapply.scala new file mode 100644 index 0000000000..2f3e4ad6cd --- /dev/null +++ b/test/files/pos/rangepos-anonapply.scala @@ -0,0 +1,9 @@ +class Test { + trait PropTraverser { + def apply(x: Int): Unit = {} + } + + def gather(x: Int) { + (new PropTraverser {})(x) + } +} diff --git a/test/files/pos/t5899.flags b/test/files/pos/t5899.flags new file mode 100644 index 0000000000..e8fb65d50c --- /dev/null +++ b/test/files/pos/t5899.flags @@ -0,0 +1 @@ +-Xfatal-warnings
\ No newline at end of file diff --git a/test/files/pos/t5899.scala b/test/files/pos/t5899.scala new file mode 100644 index 0000000000..b16f1f84fe --- /dev/null +++ b/test/files/pos/t5899.scala @@ -0,0 +1,19 @@ +import scala.tools.nsc._ + +trait Foo { + val global: Global + import global.{Name, Symbol, nme} + + case class Bippy(name: Name) + + def f(x: Bippy, sym: Symbol): Int = { + // no warning (!) for + // val Stable = sym.name.toTermName + + val Stable = sym.name + Bippy(Stable) match { + case Bippy(nme.WILDCARD) => 1 + case Bippy(Stable) => 2 // should not be considered unreachable + } + } +}
\ No newline at end of file diff --git a/test/files/run/collection-conversions.check b/test/files/run/collection-conversions.check index 08d0fa32c5..5e43d25f7e 100644 --- a/test/files/run/collection-conversions.check +++ b/test/files/run/collection-conversions.check @@ -11,6 +11,7 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing Vector --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -24,6 +25,7 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing List --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -37,6 +39,7 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing Buffer --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -50,6 +53,7 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing ParVector --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -63,6 +67,21 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK +-- Testing ParArray --- + :[Direct] Vector : OK + :[Copy] Vector : OK + :[Direct] Buffer : OK + :[Copy] Buffer : OK + :[Direct] GenSeq : OK + :[Copy] GenSeq : OK + :[Copy] Seq : OK + :[Direct] Stream : OK + :[Copy] Stream : OK + :[Direct] Array : OK + :[Copy] Array : OK + :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing Set --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -76,6 +95,7 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing SetView --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -89,6 +109,7 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK -- Testing BufferView --- :[Direct] Vector : OK :[Copy] Vector : OK @@ -102,3 +123,4 @@ :[Direct] Array : OK :[Copy] Array : OK :[Copy] ParVector: OK + :[Copy] ParArray : OK
\ No newline at end of file diff --git a/test/files/run/collection-conversions.scala b/test/files/run/collection-conversions.scala index b5c4d8e261..6d90caee4b 100644 --- a/test/files/run/collection-conversions.scala +++ b/test/files/run/collection-conversions.scala @@ -1,6 +1,7 @@ import collection._ import mutable.Buffer import parallel.immutable.ParVector +import parallel.mutable.ParArray import reflect.ClassTag object Test { @@ -29,6 +30,7 @@ object Test { val testStream = Stream(1,2,3) val testArray = Array(1,2,3) val testParVector = ParVector(1,2,3) + val testParArray = ParArray(1,2,3) def testConversion[A: ClassTag](name: String, col: => GenTraversableOnce[A]): Unit = { val tmp = col @@ -45,14 +47,16 @@ object Test { printResult("[Direct] Array ", col.toArray, testArray) printResult("[Copy] Array ", col.convertTo[Array], testArray) printResult("[Copy] ParVector", col.convertTo[ParVector], testParVector) + printResult("[Copy] ParArray ", col.convertTo[ParArray], testParArray) } def main(args: Array[String]): Unit = { - testConversion("iterator", (1 to 3).iterator) + testConversion("iterator", (1 to 3).iterator) testConversion("Vector", Vector(1,2,3)) testConversion("List", List(1,2,3)) testConversion("Buffer", Buffer(1,2,3)) testConversion("ParVector", ParVector(1,2,3)) + testConversion("ParArray", ParArray(1,2,3)) testConversion("Set", Set(1,2,3)) testConversion("SetView", Set(1,2,3).view) testConversion("BufferView", Buffer(1,2,3).view) diff --git a/test/files/run/macro-reify-splice-splice/Macros_1.scala b/test/files/run/macro-reify-splice-splice/Macros_1.scala index 030a0a217e..4f1b600f63 100644 --- a/test/files/run/macro-reify-splice-splice/Macros_1.scala +++ b/test/files/run/macro-reify-splice-splice/Macros_1.scala @@ -1,5 +1,4 @@ import scala.reflect.makro.{Context => Ctx} -import scala.reflect.{mirror => mr} object Macros { def foo = macro Impls.foo diff --git a/test/files/run/t5914.check b/test/files/run/t5914.check new file mode 100644 index 0000000000..818e321255 --- /dev/null +++ b/test/files/run/t5914.check @@ -0,0 +1 @@ +correct diff --git a/test/files/run/t5914.scala b/test/files/run/t5914.scala new file mode 100644 index 0000000000..45d8815738 --- /dev/null +++ b/test/files/run/t5914.scala @@ -0,0 +1,23 @@ +import scala.reflect.ClassTag + +trait Trees { + class Tree + implicit val ttTag: ClassTag[TypeTree] + type TypeTree <: Tree + val TypeTree: TypeTreeExtractor + abstract class TypeTreeExtractor { + def unapply(t: TypeTree): Option[String] + } + def test(tree: Tree) = + tree match { + case TypeTree(_) => println("lolwut") + case null => println("correct") + } +} + +object Test extends App with Trees { + val ttTag = implicitly[ClassTag[TypeTree]] + case class TypeTree(meh: String) extends Tree + object TypeTree extends TypeTreeExtractor + test(null) // should not crash +}
\ No newline at end of file diff --git a/test/files/run/t5971.check b/test/files/run/t5971.check new file mode 100644 index 0000000000..0c36a1ff02 --- /dev/null +++ b/test/files/run/t5971.check @@ -0,0 +1,4 @@ +r,b +r +a,b +r,a,b
\ No newline at end of file diff --git a/test/files/run/t5971.scala b/test/files/run/t5971.scala new file mode 100644 index 0000000000..dbd9beebb3 --- /dev/null +++ b/test/files/run/t5971.scala @@ -0,0 +1,23 @@ + + + + + +/** When using `AbstractTransformed` abstract inner class in views in order + * to force generating bridges, one must take care to push the corresponding + * collection trait (such as `Iterable` or `Seq`) as far as possible to the + * left in the linearization order -- otherwise, overridden methods from these + * traits can override the already overridden methods in view. This was the + * case with `takeWhile`. + * Mind blowing, I know. + */ +object Test { + + def main(args: Array[String]) { + println("bar".view.reverse.filter(_ > 'a').mkString(",")) + println("bar".view.reverse.take(1).mkString(",")) + println("bar".view.reverse.dropWhile(_ > 'a').mkString(",")) + println("bar".view.reverse.takeWhile(_ => true).mkString(",")) + } + +} diff --git a/test/files/run/t5986.check b/test/files/run/t5986.check new file mode 100644 index 0000000000..4101770c6d --- /dev/null +++ b/test/files/run/t5986.check @@ -0,0 +1,15 @@ +Foo(bar, 1) +Foo(bar, 1) +Foo(bar, 1),Foo(baz, 3),Foo(bazz, 4) +Foo(bar, 1) +Foo(bar, 1) +Foo(bar, 1),Foo(baz, 3),Foo(bazz, 4) +Foo(bar, 1) +Foo(bar, 1) +Foo(bar, 1),Foo(baz, 3),Foo(bazz, 4) +Foo(bar, 1) +Foo(bar, 1) +Foo(bar, 1),Foo(baz, 3),Foo(bazz, 4) +Foo(bar, 1) +Foo(bar, 1) +Foo(bar, 1),Foo(baz, 3),Foo(bazz, 4)
\ No newline at end of file diff --git a/test/files/run/t5986.scala b/test/files/run/t5986.scala new file mode 100644 index 0000000000..8cf7086f98 --- /dev/null +++ b/test/files/run/t5986.scala @@ -0,0 +1,36 @@ + + + +import scala.collection._ + + + +/** A sorted set should not replace elements when adding + * and the element already exists in the set. + */ +object Test { + + class Foo(val name: String, val n: Int) { + override def equals(obj: Any): Boolean = obj match { case other: Foo => name == other.name; case _ => false } + override def hashCode = name.## + override def toString = "Foo(" + name + ", " + n + ")" + } + + implicit val ordering: Ordering[Foo] = Ordering.fromLessThan[Foo] { (a, b) => a.name.compareTo(b.name) < 0 } + + def check[S <: Set[Foo]](set: S) { + def output(s: Set[Foo]) = println(s.toList.sorted.mkString(",")) + output(set + new Foo("bar", 2)) + output(set ++ List(new Foo("bar", 2), new Foo("bar", 3), new Foo("bar", 4))) + output(set union Set(new Foo("bar", 2), new Foo("baz", 3), new Foo("bazz", 4))) + } + + def main(args: Array[String]) { + check(Set(new Foo("bar", 1))) + check(immutable.Set(new Foo("bar", 1))) + check(mutable.Set(new Foo("bar", 1))) + check(immutable.SortedSet(new Foo("bar", 1))) + check(mutable.SortedSet(new Foo("bar", 1))) + } + +} diff --git a/test/files/scalacheck/redblacktree.scala b/test/files/scalacheck/redblacktree.scala index e4b356c889..e2609fa200 100644 --- a/test/files/scalacheck/redblacktree.scala +++ b/test/files/scalacheck/redblacktree.scala @@ -121,7 +121,7 @@ package scala.collection.immutable.redblacktree { override type ModifyParm = Int override def genParm(tree: Tree[String, Int]): Gen[ModifyParm] = choose(0, iterator(tree).size + 1) - override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = update(tree, generateKey(tree, parm), 0) + override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = update(tree, generateKey(tree, parm), 0, true) def generateKey(tree: Tree[String, Int], parm: ModifyParm): String = nodeAt(tree, parm) match { case Some((key, _)) => key.init.mkString + "MN" @@ -144,7 +144,7 @@ package scala.collection.immutable.redblacktree { override type ModifyParm = Int override def genParm(tree: Tree[String, Int]): Gen[ModifyParm] = choose(0, iterator(tree).size) override def modify(tree: Tree[String, Int], parm: ModifyParm): Tree[String, Int] = nodeAt(tree, parm) map { - case (key, _) => update(tree, key, newValue) + case (key, _) => update(tree, key, newValue, true) } getOrElse tree property("update modifies values") = forAll(genInput) { case (tree, parm, newTree) => |