summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala26
-rw-r--r--src/compiler/scala/tools/nsc/reporters/Reporter.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala22
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala35
-rw-r--r--src/library/scala/Symbol.scala5
-rw-r--r--src/library/scala/collection/IterableLike.scala3
-rw-r--r--src/library/scala/collection/SeqLike.scala1
-rw-r--r--src/library/scala/collection/TraversableLike.scala5
-rw-r--r--src/library/scala/collection/TraversableViewLike.scala13
-rw-r--r--src/library/scala/collection/immutable/Stream.scala1
-rw-r--r--src/library/scala/collection/mutable/FlatHashTable.scala13
-rw-r--r--src/library/scala/collection/mutable/IndexedSeqLike.scala1
-rw-r--r--src/library/scala/collection/mutable/ListBuffer.scala98
-rw-r--r--src/library/scala/collection/mutable/MultiMap.scala35
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala29
-rw-r--r--src/library/scala/collection/parallel/ParSeqLike.scala3
-rw-r--r--src/library/scala/concurrent/Future.scala23
-rw-r--r--src/library/scala/concurrent/package.scala5
-rw-r--r--src/partest/scala/tools/partest/DirectTest.scala8
-rw-r--r--src/partest/scala/tools/partest/StoreReporterDirectTest.scala15
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala17
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala33
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala80
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala7
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala14
-rw-r--r--test/files/neg/t5148.check10
-rw-r--r--test/files/neg/t6357.check4
-rw-r--r--test/files/neg/t6357.scala6
-rw-r--r--test/files/neg/t6663.check6
-rw-r--r--test/files/neg/t6663.scala19
-rw-r--r--test/files/pos/t6551.scala13
-rw-r--r--test/files/pos/t6624.scala28
-rw-r--r--test/files/pos/t6648.scala24
-rw-r--r--test/files/run/rawstrings.check2
-rw-r--r--test/files/run/rawstrings.scala2
-rw-r--r--test/files/run/showraw_aliases.check4
-rw-r--r--test/files/run/showraw_aliases.scala6
-rw-r--r--test/files/run/t6023.check12
-rw-r--r--test/files/run/t6023.scala17
-rw-r--r--test/files/run/t6440.check5
-rw-r--r--test/files/run/t6440.scala47
-rw-r--r--test/files/run/t6440b.check4
-rw-r--r--test/files/run/t6440b.scala61
-rw-r--r--test/files/run/t6628.check2
-rw-r--r--test/files/run/t6628.scala11
-rw-r--r--test/files/run/t6632.check3
-rw-r--r--test/files/run/t6632.scala29
-rw-r--r--test/files/run/t6633.check3
-rw-r--r--test/files/run/t6633.scala33
-rw-r--r--test/files/run/t6634.check31
-rw-r--r--test/files/run/t6634.scala80
-rw-r--r--test/files/run/t6644.scala8
-rw-r--r--test/files/run/t6646.check5
-rw-r--r--test/files/run/t6646.scala19
-rw-r--r--test/files/run/t6663.check1
-rw-r--r--test/files/run/t6663.scala17
-rw-r--r--test/files/run/t6673.check1
-rw-r--r--test/files/run/t6673.scala5
-rw-r--r--test/files/run/t6677.scala28
-rw-r--r--test/files/run/t6677b.scala33
-rw-r--r--test/files/run/t6687.scala10
-rw-r--r--test/files/run/t6695.scala18
-rw-r--r--test/files/run/t6706.scala14
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_lookup.check5
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_lookup.scala14
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check5
-rw-r--r--test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala15
-rwxr-xr-xtools/epfl-publish2
75 files changed, 963 insertions, 246 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 0d13623e0c..0ac46a18bc 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -285,7 +285,7 @@ abstract class TreeBuilder {
def makeGenerator(pos: Position, pat: Tree, valeq: Boolean, rhs: Tree): Enumerator = {
val pat1 = patvarTransformer.transform(pat)
val rhs1 =
- if (valeq || treeInfo.isVariablePattern(pat)) rhs
+ if (valeq || treeInfo.isVarPatternDeep(pat)) rhs
else makeFilter(rhs, pat1.duplicate, nme.CHECK_IF_REFUTABLE_STRING)
if (valeq) ValEq(pos, pat1, rhs1)
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 8dd7e7801e..3ae1210ebf 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -493,28 +493,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def inheritanceDiagram = makeInheritanceDiagram(this)
def contentDiagram = makeContentDiagram(this)
- def groupSearch[T](extractor: Comment => T, default: T): T = {
- // query this template
- if (comment.isDefined) {
- val entity = extractor(comment.get)
- if (entity != default) return entity
+ def groupSearch[T](extractor: Comment => Option[T]): Option[T] = {
+ val comments = comment +: linearizationTemplates.collect { case dtpl: DocTemplateImpl => dtpl.comment }
+ comments.flatten.map(extractor).flatten.headOption orElse {
+ Option(inTpl) flatMap (_.groupSearch(extractor))
}
- // query linearization
- if (!sym.isPackage)
- for (tpl <- linearizationTemplates.collect{ case dtpl: DocTemplateImpl if dtpl!=this => dtpl}) {
- val entity = tpl.groupSearch(extractor, default)
- if (entity != default) return entity
- }
- // query inTpl, going up the ownerChain
- if (inTpl != null)
- inTpl.groupSearch(extractor, default)
- else
- default
}
- def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group), if (group == defaultGroup) defaultGroupDesc else None)
- def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group) match { case Some(prio) => prio; case _ => 0 }, if (group == defaultGroup) defaultGroupPriority else 0)
- def groupName(group: String): String = groupSearch(_.groupNames.get(group) match { case Some(name) => name; case _ => group }, if (group == defaultGroup) defaultGroupName else group)
+ def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group)) orElse { if (group == defaultGroup) defaultGroupDesc else None }
+ def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group)) getOrElse { if (group == defaultGroup) defaultGroupPriority else 0 }
+ def groupName(group: String): String = groupSearch(_.groupNames.get(group)) getOrElse { if (group == defaultGroup) defaultGroupName else group }
}
abstract class PackageImpl(sym: Symbol, inTpl: PackageImpl) extends DocTemplateImpl(sym, inTpl) with Package {
diff --git a/src/compiler/scala/tools/nsc/reporters/Reporter.scala b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
index c5321dd728..8871ae6555 100644
--- a/src/compiler/scala/tools/nsc/reporters/Reporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/Reporter.scala
@@ -20,9 +20,15 @@ abstract class Reporter {
class Severity(val id: Int) extends severity.Value {
var count: Int = 0
}
- val INFO = new Severity(0)
- val WARNING = new Severity(1)
- val ERROR = new Severity(2)
+ val INFO = new Severity(0) {
+ override def toString: String = "INFO"
+ }
+ val WARNING = new Severity(1) {
+ override def toString: String = "WARNING"
+ }
+ val ERROR = new Severity(2) {
+ override def toString: String = "ERROR"
+ }
/** Whether very long lines can be truncated. This exists so important
* debugging information (like printing the classpath) is not rendered
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 92743919ec..7b9b13ae1c 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -693,7 +693,7 @@ abstract class Erasure extends AddInterfaces
adaptToType(unbox(tree, pt), pt)
else if (isPrimitiveValueType(tree.tpe) && !isPrimitiveValueType(pt)) {
adaptToType(box(tree, pt.toString), pt)
- } else if (tree.tpe.isInstanceOf[MethodType] && tree.tpe.params.isEmpty) {
+ } else if (isMethodTypeWithEmptyParams(tree.tpe)) {
// [H] this assert fails when trying to typecheck tree !(SomeClass.this.bitmap) for single lazy val
//assert(tree.symbol.isStable, "adapt "+tree+":"+tree.tpe+" to "+pt)
adaptToType(Apply(tree, List()) setPos tree.pos setType tree.tpe.resultType, pt)
@@ -783,16 +783,21 @@ abstract class Erasure extends AddInterfaces
else if (!isPrimitiveValueType(qual1.tpe) && isPrimitiveValueMember(tree.symbol))
qual1 = unbox(qual1, tree.symbol.owner.tpe)
- if (isPrimitiveValueMember(tree.symbol) && !isPrimitiveValueType(qual1.tpe))
+ def selectFrom(qual: Tree) = treeCopy.Select(tree, qual, name)
+
+ if (isPrimitiveValueMember(tree.symbol) && !isPrimitiveValueType(qual1.tpe)) {
tree.symbol = NoSymbol
- else if (qual1.tpe.isInstanceOf[MethodType] && qual1.tpe.params.isEmpty) {
+ selectFrom(qual1)
+ } else if (isMethodTypeWithEmptyParams(qual1.tpe)) {
assert(qual1.symbol.isStable, qual1.symbol);
- qual1 = Apply(qual1, List()) setPos qual1.pos setType qual1.tpe.resultType
+ val applied = Apply(qual1, List()) setPos qual1.pos setType qual1.tpe.resultType
+ adaptMember(selectFrom(applied))
} else if (!(qual1.isInstanceOf[Super] || (qual1.tpe.typeSymbol isSubClass tree.symbol.owner))) {
assert(tree.symbol.owner != ArrayClass)
- qual1 = cast(qual1, tree.symbol.owner.tpe)
+ selectFrom(cast(qual1, tree.symbol.owner.tpe))
+ } else {
+ selectFrom(qual1)
}
- treeCopy.Select(tree, qual1, name)
}
case SelectFromArray(qual, name, erasure) =>
var qual1 = typedQualifier(qual)
@@ -870,6 +875,11 @@ abstract class Erasure extends AddInterfaces
tree1
}
}
+
+ private def isMethodTypeWithEmptyParams(tpe: Type) = tpe match {
+ case MethodType(Nil, _) => true
+ case _ => false
+ }
}
/** The erasure transformer */
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 6cc957a9eb..6f3d7932a5 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -173,9 +173,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
List(This(currentOwner)))
val extensionCall = atOwner(origMeth) {
localTyper.typedPos(rhs.pos) {
- (extensionCallPrefix /: vparamss) {
- case (fn, params) => Apply(fn, params map (param => Ident(param.symbol)))
- }
+ gen.mkForwarder(extensionCallPrefix, mmap(vparamss)(_.symbol))
}
}
deriveDefDef(tree)(_ => extensionCall)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index f6b55b6606..529009a058 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -369,7 +369,7 @@ abstract class UnCurry extends InfoTransform
}
val isDefinedAtMethodDef = {
- val methSym = anonClass.newMethod(nme.isDefinedAt, fun.pos, FINAL)
+ val methSym = anonClass.newMethod(nme.isDefinedAt, fun.pos, FINAL | SYNTHETIC)
val params = methSym newSyntheticValueParams formals
methSym setInfoAndEnter MethodType(params, BooleanClass.tpe)
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index e8a2c9f43c..acc4f7ff67 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -426,6 +426,7 @@ trait MethodSynthesis {
// spot that brand of them. In other words it's an artifact of the implementation.
val tpt = derivedSym.tpe.finalResultType match {
case ExistentialType(_, _) => TypeTree()
+ case _ if mods.isDeferred => TypeTree()
case tp => TypeTree(tp)
}
tpt setPos derivedSym.pos.focus
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index f5d4df14fe..36edd46f25 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1289,7 +1289,8 @@ trait Namers extends MethodSynthesis {
if (clazz.isDerivedValueClass) {
log("Ensuring companion for derived value class " + name + " at " + cdef.pos.show)
clazz setFlag FINAL
- enclosingNamerWithScope(clazz.owner.info.decls).ensureCompanionObject(cdef)
+ // Don't force the owner's info lest we create cycles as in SI-6357.
+ enclosingNamerWithScope(clazz.owner.rawInfo.decls).ensureCompanionObject(cdef)
}
result
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 31db042942..834c64aaae 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -417,7 +417,17 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// (the prefix of the argument passed to the unapply must equal the prefix of the type of the binder)
val treeMaker = TypeTestTreeMaker(patBinder, patBinder, extractor.paramType, extractor.paramType)(pos, extractorArgTypeTest = true)
(List(treeMaker), treeMaker.nextBinder)
- } else (Nil, patBinder)
+ } else {
+ // no type test needed, but the tree maker relies on `patBinderOrCasted` having type `extractor.paramType` (and not just some type compatible with it)
+ // SI-6624 shows this is necessary because apparently patBinder may have an unfortunate type (.decls don't have the case field accessors)
+ // TODO: get to the bottom of this -- I assume it happens when type checking infers a weird type for an unapply call
+ // by going back to the parameterType for the extractor call we get a saner type, so let's just do that for now
+ /* TODO: uncomment when `settings.developer` and `devWarning` become available
+ if (settings.developer.value && !(patBinder.info =:= extractor.paramType))
+ devWarning(s"resetting info of $patBinder: ${patBinder.info} to ${extractor.paramType}")
+ */
+ (Nil, patBinder setInfo extractor.paramType)
+ }
withSubPats(typeTestTreeMaker :+ extractor.treeMaker(patBinderOrCasted, pos), extractor.subBindersAndPatterns: _*)
}
@@ -1143,7 +1153,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// ExplicitOuter replaces `Select(q, outerSym) OBJ_EQ expectedPrefix` by `Select(q, outerAccessor(outerSym.owner)) OBJ_EQ expectedPrefix`
// if there's an outer accessor, otherwise the condition becomes `true` -- TODO: can we improve needsOuterTest so there's always an outerAccessor?
- val outer = expectedTp.typeSymbol.newMethod(vpmName.outer) setInfo expectedTp.prefix setFlag SYNTHETIC | ARTIFACT
+ val outer = expectedTp.typeSymbol.newMethod(vpmName.outer, newFlags = SYNTHETIC | ARTIFACT) setInfo expectedTp.prefix
(Select(codegen._asInstanceOf(testedBinder, expectedTp), outer)) OBJ_EQ expectedOuter
}
@@ -1405,7 +1415,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
// assert(owner ne null); assert(owner ne NoSymbol)
def freshSym(pos: Position, tp: Type = NoType, prefix: String = "x") =
- NoSymbol.newTermSymbol(freshName(prefix), pos) setInfo tp
+ NoSymbol.newTermSymbol(freshName(prefix), pos, newFlags = SYNTHETIC) setInfo tp
def newSynthCaseLabel(name: String) =
NoSymbol.newLabel(freshName(name), NoPosition) setFlag treeInfo.SYNTH_CASE_FLAGS
@@ -3601,7 +3611,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
*/
def matcher(scrut: Tree, scrutSym: Symbol, restpe: Type)(cases: List[Casegen => Tree], matchFailGen: Option[Tree => Tree]): Tree = {
val matchEnd = newSynthCaseLabel("matchEnd")
- val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, SYNTHETIC) setInfo restpe.withoutAnnotations
+ val matchRes = NoSymbol.newValueParameter(newTermName("x"), NoPosition, newFlags = SYNTHETIC) setInfo restpe.withoutAnnotations
matchEnd setInfo MethodType(List(matchRes), restpe)
def newCaseSym = newSynthCaseLabel("case") setInfo MethodType(Nil, restpe)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 034de203c9..5714c2c109 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1100,6 +1100,10 @@ trait Typers extends Modes with Adaptations with Tags {
instantiateToMethodType(mt)
case _ =>
+ def shouldInsertApply(tree: Tree) = inAllModes(mode, EXPRmode | FUNmode) && (tree.tpe match {
+ case _: MethodType | _: OverloadedType | _: PolyType => false
+ case _ => applyPossible
+ })
def applyPossible = {
def applyMeth = member(adaptToName(tree, nme.apply), nme.apply)
dyna.acceptsApplyDynamic(tree.tpe) || (
@@ -1113,14 +1117,12 @@ trait Typers extends Modes with Adaptations with Tags {
adaptType()
else if (
inExprModeButNot(mode, FUNmode) && !tree.isDef && // typechecking application
- tree.symbol != null && tree.symbol.isTermMacro) // of a macro
+ tree.symbol != null && tree.symbol.isTermMacro && // of a macro
+ !tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined)
macroExpand(this, tree, mode, pt)
else if ((mode & (PATTERNmode | FUNmode)) == (PATTERNmode | FUNmode))
adaptConstrPattern()
- else if (inAllModes(mode, EXPRmode | FUNmode) &&
- !tree.tpe.isInstanceOf[MethodType] &&
- !tree.tpe.isInstanceOf[OverloadedType] &&
- applyPossible)
+ else if (shouldInsertApply(tree))
insertApply()
else if (!context.undetparams.isEmpty && !inPolyMode(mode)) { // (9)
assert(!inHKMode(mode), modeString(mode)) //@M
@@ -3935,9 +3937,14 @@ trait Typers extends Modes with Adaptations with Tags {
case t: ValOrDefDef => t.rhs
case t => t
}
- val (outer, explicitTargs) = cxTree1 match {
+ val cxTree2 = cxTree1 match {
+ case Typed(t, tpe) => t // ignore outer type annotation
+ case t => t
+ }
+ val (outer, explicitTargs) = cxTree2 match {
case TypeApply(fun, targs) => (fun, targs)
case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
+ case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs)
case t => (t, Nil)
}
def hasNamedArg(as: List[Tree]) = as.collectFirst{case AssignOrNamedArg(lhs, rhs) =>}.nonEmpty
@@ -5215,9 +5222,9 @@ trait Typers extends Modes with Adaptations with Tags {
// find out whether the programmer is trying to eta-expand a macro def
// to do that we need to typecheck the tree first (we need a symbol of the eta-expandee)
// that typecheck must not trigger macro expansions, so we explicitly prohibit them
- // Q: "but, " - you may ask - ", `typed1` doesn't call adapt, which does macro expansion, so why explicit check?"
- // A: solely for robustness reasons. this mechanism might change in the future, which might break unprotected code
- val exprTyped = context.withMacrosDisabled(typed1(expr, mode, pt))
+ // however we cannot do `context.withMacrosDisabled`
+ // because `expr` might contain nested macro calls (see SI-6673)
+ val exprTyped = typed1(expr updateAttachment SuppressMacroExpansionAttachment, mode, pt)
exprTyped match {
case macroDef if macroDef.symbol != null && macroDef.symbol.isTermMacro && !macroDef.symbol.isErroneous =>
MacroEtaError(exprTyped)
@@ -5361,8 +5368,14 @@ trait Typers extends Modes with Adaptations with Tags {
}
def typedTypeTree(tree: TypeTree) = {
- if (tree.original != null)
- tree setType typedType(tree.original, mode).tpe
+ if (tree.original != null) {
+ val newTpt = typedType(tree.original, mode)
+ tree setType newTpt.tpe
+ newTpt match {
+ case tt @ TypeTree() => tree setOriginal tt.original
+ case _ => tree
+ }
+ }
else
// we should get here only when something before failed
// and we try again (@see tryTypedApply). In that case we can assign
diff --git a/src/library/scala/Symbol.scala b/src/library/scala/Symbol.scala
index 723c05a30c..4fead7a50c 100644
--- a/src/library/scala/Symbol.scala
+++ b/src/library/scala/Symbol.scala
@@ -69,6 +69,11 @@ private[scala] abstract class UniquenessCache[K, V >: Null]
val res = cached()
if (res != null) res
else {
+ // If we don't remove the old String key from the map, we can
+ // wind up with one String as the key and a different String as
+ // as the name field in the Symbol, which can lead to surprising
+ // GC behavior and duplicate Symbols. See SI-6706.
+ map remove name
val sym = valueFromKey(name)
map.put(name, new WeakReference(sym))
sym
diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala
index 8d1fa80815..540bd84b79 100644
--- a/src/library/scala/collection/IterableLike.scala
+++ b/src/library/scala/collection/IterableLike.scala
@@ -171,7 +171,7 @@ self =>
* fewer elements than size.
*/
def sliding(size: Int): Iterator[Repr] = sliding(size, 1)
-
+
/** Groups elements in fixed size blocks by passing a "sliding window"
* over them (as opposed to partitioning them, as is done in grouped.)
* @see [[scala.collection.Iterator]], method `sliding`
@@ -293,7 +293,6 @@ self =>
override /*TraversableLike*/ def view = new IterableView[A, Repr] {
protected lazy val underlying = self.repr
- override def isEmpty = self.isEmpty
override def iterator = self.iterator
}
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index 0ffd99c88c..6871a3cb73 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -630,7 +630,6 @@ trait SeqLike[+A, +Repr] extends Any with IterableLike[A, Repr] with GenSeqLike[
override def view = new SeqView[A, Repr] {
protected lazy val underlying = self.repr
- override def isEmpty = self.isEmpty
override def iterator = self.iterator
override def length = self.length
override def apply(idx: Int) = self.apply(idx)
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index fc7202b96b..5f193eb211 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -86,7 +86,7 @@ trait TraversableLike[+A, +Repr] extends Any
def repr: Repr = this.asInstanceOf[Repr]
final def isTraversableAgain: Boolean = true
-
+
/** The underlying collection seen as an instance of `$Coll`.
* By default this is implemented as the current collection object itself,
* but this can be overridden.
@@ -174,7 +174,7 @@ trait TraversableLike[+A, +Repr] extends Any
*
* @usecase def ++:[B](that: TraversableOnce[B]): $Coll[B]
* @inheritdoc
- *
+ *
* Example:
* {{{
* scala> val x = List(1)
@@ -660,7 +660,6 @@ trait TraversableLike[+A, +Repr] extends Any
def view = new TraversableView[A, Repr] {
protected lazy val underlying = self.repr
override def foreach[U](f: A => U) = self foreach f
- override def isEmpty = self.isEmpty
}
/** Creates a non-strict view of a slice of this $coll.
diff --git a/src/library/scala/collection/TraversableViewLike.scala b/src/library/scala/collection/TraversableViewLike.scala
index 0925fe4770..14f865c2f0 100644
--- a/src/library/scala/collection/TraversableViewLike.scala
+++ b/src/library/scala/collection/TraversableViewLike.scala
@@ -59,7 +59,7 @@ trait ViewMkString[+A] {
* $viewInfo
*
* All views for traversable collections are defined by creating a new `foreach` method.
- *
+ *
* @author Martin Odersky
* @version 2.8
* @since 2.8
@@ -162,7 +162,7 @@ trait TraversableViewLike[+A,
// if (b.isInstanceOf[NoBuilder[_]]) newFlatMapped(f).asInstanceOf[That]
// else super.flatMap[B, That](f)(bf)
}
- override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]) =
+ override def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]) =
newFlatMapped(asTraversable)
private[this] implicit def asThis(xs: Transformed[A]): This = xs.asInstanceOf[This]
@@ -193,15 +193,6 @@ trait TraversableViewLike[+A,
override def span(p: A => Boolean): (This, This) = (newTakenWhile(p), newDroppedWhile(p))
override def splitAt(n: Int): (This, This) = (newTaken(n), newDropped(n))
- // Without this, isEmpty tests go back to the Traversable default, which
- // involves starting a foreach, which can force the first element of the
- // view. This is just a backstop - it's overridden at all the "def view"
- // instantiation points in the collections where the Coll type is known.
- override def isEmpty = underlying match {
- case x: GenTraversableOnce[_] => x.isEmpty
- case _ => super.isEmpty
- }
-
override def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[This, B, That]): That =
newForced(thisSeq.scanLeft(z)(op)).asInstanceOf[That]
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 426ab6f0fb..be2cd91c68 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -937,7 +937,6 @@ self =>
override def view = new StreamView[A, Stream[A]] {
protected lazy val underlying = self.repr
- override def isEmpty = self.isEmpty
override def iterator = self.iterator
override def length = self.length
override def apply(idx: Int) = self.apply(idx)
diff --git a/src/library/scala/collection/mutable/FlatHashTable.scala b/src/library/scala/collection/mutable/FlatHashTable.scala
index c0299479f3..91e95e039b 100644
--- a/src/library/scala/collection/mutable/FlatHashTable.scala
+++ b/src/library/scala/collection/mutable/FlatHashTable.scala
@@ -110,24 +110,23 @@ trait FlatHashTable[A] extends FlatHashTable.HashUtils[A] {
/** Finds an entry in the hash table if such an element exists. */
protected def findEntry(elem: A): Option[A] = {
- var h = index(elemHashCode(elem))
- var entry = table(h)
- while (null != entry && entry != elem) {
- h = (h + 1) % table.length
- entry = table(h)
- }
+ val entry = findEntryImpl(elem)
if (null == entry) None else Some(entry.asInstanceOf[A])
}
/** Checks whether an element is contained in the hash table. */
protected def containsEntry(elem: A): Boolean = {
+ null != findEntryImpl(elem)
+ }
+
+ private def findEntryImpl(elem: A): AnyRef = {
var h = index(elemHashCode(elem))
var entry = table(h)
while (null != entry && entry != elem) {
h = (h + 1) % table.length
entry = table(h)
}
- null != entry
+ entry
}
/** Add entry if not yet in table.
diff --git a/src/library/scala/collection/mutable/IndexedSeqLike.scala b/src/library/scala/collection/mutable/IndexedSeqLike.scala
index 21cff70473..f0c31ec7fb 100644
--- a/src/library/scala/collection/mutable/IndexedSeqLike.scala
+++ b/src/library/scala/collection/mutable/IndexedSeqLike.scala
@@ -53,7 +53,6 @@ trait IndexedSeqLike[A, +Repr] extends Any with scala.collection.IndexedSeqLike[
*/
override def view = new IndexedSeqView[A, Repr] {
protected lazy val underlying = self.repr
- override def isEmpty = self.isEmpty
override def iterator = self.iterator
override def length = self.length
override def apply(idx: Int) = self.apply(idx)
diff --git a/src/library/scala/collection/mutable/ListBuffer.scala b/src/library/scala/collection/mutable/ListBuffer.scala
index 53b2b57f50..67af4a6bd6 100644
--- a/src/library/scala/collection/mutable/ListBuffer.scala
+++ b/src/library/scala/collection/mutable/ListBuffer.scala
@@ -129,29 +129,27 @@ final class ListBuffer[A]
* @throws Predef.IndexOutOfBoundsException if `n` is out of bounds.
*/
def update(n: Int, x: A) {
- try {
- if (exported) copy()
- if (n == 0) {
- val newElem = new :: (x, start.tail);
- if (last0 eq start) {
- last0 = newElem
- }
- start = newElem
- } else {
- var cursor = start
- var i = 1
- while (i < n) {
- cursor = cursor.tail
- i += 1
- }
- val newElem = new :: (x, cursor.tail.tail)
- if (last0 eq cursor.tail) {
- last0 = newElem
- }
- cursor.asInstanceOf[::[A]].tl = newElem
+ // We check the bounds early, so that we don't trigger copying.
+ if (n < 0 || n >= len) throw new IndexOutOfBoundsException(n.toString)
+ if (exported) copy()
+ if (n == 0) {
+ val newElem = new :: (x, start.tail);
+ if (last0 eq start) {
+ last0 = newElem
+ }
+ start = newElem
+ } else {
+ var cursor = start
+ var i = 1
+ while (i < n) {
+ cursor = cursor.tail
+ i += 1
+ }
+ val newElem = new :: (x, cursor.tail.tail)
+ if (last0 eq cursor.tail) {
+ last0 = newElem
}
- } catch {
- case ex: Exception => throw new IndexOutOfBoundsException(n.toString())
+ cursor.asInstanceOf[::[A]].tl = newElem
}
}
@@ -212,34 +210,31 @@ final class ListBuffer[A]
* @throws Predef.IndexOutOfBoundsException if `n` is out of bounds.
*/
def insertAll(n: Int, seq: Traversable[A]) {
- try {
- if (exported) copy()
- var elems = seq.toList.reverse
- len += elems.length
- if (n == 0) {
- while (!elems.isEmpty) {
- val newElem = new :: (elems.head, start)
- if (start.isEmpty) last0 = newElem
- start = newElem
- elems = elems.tail
- }
- } else {
- var cursor = start
- var i = 1
- while (i < n) {
- cursor = cursor.tail
- i += 1
- }
- while (!elems.isEmpty) {
- val newElem = new :: (elems.head, cursor.tail)
- if (cursor.tail.isEmpty) last0 = newElem
- cursor.asInstanceOf[::[A]].tl = newElem
- elems = elems.tail
- }
+ // We check the bounds early, so that we don't trigger copying.
+ if (n < 0 || n > len) throw new IndexOutOfBoundsException(n.toString)
+ if (exported) copy()
+ var elems = seq.toList.reverse
+ len += elems.length
+ if (n == 0) {
+ while (!elems.isEmpty) {
+ val newElem = new :: (elems.head, start)
+ if (start.isEmpty) last0 = newElem
+ start = newElem
+ elems = elems.tail
+ }
+ } else {
+ var cursor = start
+ var i = 1
+ while (i < n) {
+ cursor = cursor.tail
+ i += 1
+ }
+ while (!elems.isEmpty) {
+ val newElem = new :: (elems.head, cursor.tail)
+ if (cursor.tail.isEmpty) last0 = newElem
+ cursor.asInstanceOf[::[A]].tl = newElem
+ elems = elems.tail
}
- } catch {
- case ex: Exception =>
- throw new IndexOutOfBoundsException(n.toString())
}
}
@@ -249,7 +244,12 @@ final class ListBuffer[A]
* @param n the index which refers to the first element to remove.
* @param count the number of elements to remove.
*/
+ @annotation.migration("Invalid input values will be rejected in future releases.", "2.11")
override def remove(n: Int, count: Int) {
+ if (n >= len)
+ return
+ if (count < 0)
+ throw new IllegalArgumentException(s"removing negative number ($count) of elements")
if (exported) copy()
val n1 = n max 0
val count1 = count min (len - n1)
diff --git a/src/library/scala/collection/mutable/MultiMap.scala b/src/library/scala/collection/mutable/MultiMap.scala
index 31c8a50a84..4635bfbe64 100644
--- a/src/library/scala/collection/mutable/MultiMap.scala
+++ b/src/library/scala/collection/mutable/MultiMap.scala
@@ -15,8 +15,36 @@ package mutable
/** A trait for mutable maps with multiple values assigned to a key.
*
* This class is typically used as a mixin. It turns maps which map `A`
- * to `Set[B]` objects into multi maps which map `A` to
- * `B` objects.
+ * to `Set[B]` objects into multimaps that map `A` to `B` objects.
+ *
+ * @example {{{
+ * // first import all necessary types from package `collection.mutable`
+ * import collection.mutable.{ HashMap, MultiMap, Set }
+ *
+ * // to create a `MultiMap` the easiest way is to mixin it into a normal
+ * // `Map` instance
+ * val mm = new HashMap[Int, Set[String]] with MultiMap[Int, String]
+ *
+ * // to add key-value pairs to a multimap it is important to use
+ * // the method `addBinding` because standard methods like `+` will
+ * // overwrite the complete key-value pair instead of adding the
+ * // value to the existing key
+ * mm.addBinding(1, "a")
+ * mm.addBinding(2, "b")
+ * mm.addBinding(1, "c")
+ *
+ * // mm now contains `Map(2 -> Set(b), 1 -> Set(c, a))`
+ *
+ * // to check if the multimap contains a value there is method
+ * // `entryExists`, which allows to traverse the including set
+ * mm.entryExists(1, _ == "a") == true
+ * mm.entryExists(1, _ == "b") == false
+ * mm.entryExists(2, _ == "b") == true
+ *
+ * // to remove a previous added value there is the method `removeBinding`
+ * mm.removeBinding(1, "a")
+ * mm.entryExists(1, _ == "a") == false
+ * }}}
*
* @define coll multimap
* @define Coll `MultiMap`
@@ -57,7 +85,8 @@ trait MultiMap[A, B] extends Map[A, Set[B]] {
this
}
- /** Removes the binding of `value` to `key` if it exists.
+ /** Removes the binding of `value` to `key` if it exists, otherwise this
+ * operation doesn't have any effect.
*
* If this was the last value assigned to the specified key, the
* set assigned to that key will be removed as well.
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index 9825587b0e..0f06ff37af 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -171,9 +171,9 @@ self: ParIterableLike[T, Repr, Sequential] =>
/** The task support object which is responsible for scheduling and
* load-balancing tasks to processors.
- *
+ *
* @see [[scala.collection.parallel.TaskSupport]]
- */
+ */
def tasksupport = {
val ts = _tasksupport
if (ts eq null) {
@@ -188,18 +188,18 @@ self: ParIterableLike[T, Repr, Sequential] =>
* A task support object can be changed in a parallel collection after it
* has been created, but only during a quiescent period, i.e. while there
* are no concurrent invocations to parallel collection methods.
- *
- * Here is a way to change the task support of a parallel collection:
- *
- * {{{
- * import scala.collection.parallel._
- * val pc = mutable.ParArray(1, 2, 3)
- * pc.tasksupport = new ForkJoinTaskSupport(
- * new scala.concurrent.forkjoin.ForkJoinPool(2))
- * }}}
+ *
+ * Here is a way to change the task support of a parallel collection:
+ *
+ * {{{
+ * import scala.collection.parallel._
+ * val pc = mutable.ParArray(1, 2, 3)
+ * pc.tasksupport = new ForkJoinTaskSupport(
+ * new scala.concurrent.forkjoin.ForkJoinPool(2))
+ * }}}
*
* @see [[scala.collection.parallel.TaskSupport]]
- */
+ */
def tasksupport_=(ts: TaskSupport) = _tasksupport = ts
def seq: Sequential
@@ -848,7 +848,6 @@ self: ParIterableLike[T, Repr, Sequential] =>
override def seq = self.seq.view
def splitter = self.splitter
def size = splitter.remaining
- override def isEmpty = size == 0
}
override def toArray[U >: T: ClassTag]: Array[U] = {
@@ -878,13 +877,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])
-
+
override def toVector: Vector[T] = to[Vector]
override def to[Col[_]](implicit cbf: CanBuildFrom[Nothing, T, Col[T @uncheckedVariance]]): Col[T @uncheckedVariance] = if (cbf().isCombiner) {
toParCollection[T, Col[T]](() => cbf().asCombiner)
} else seq.to(cbf)
-
+
/* tasks */
protected trait StrictSplitterCheckTask[R, Tp] extends Task[R, Tp] {
diff --git a/src/library/scala/collection/parallel/ParSeqLike.scala b/src/library/scala/collection/parallel/ParSeqLike.scala
index 4f1c3fa7a2..201b624c72 100644
--- a/src/library/scala/collection/parallel/ParSeqLike.scala
+++ b/src/library/scala/collection/parallel/ParSeqLike.scala
@@ -44,7 +44,7 @@ trait ParSeqLike[+T, +Repr <: ParSeq[T], +Sequential <: Seq[T] with SeqLike[T, S
extends scala.collection.GenSeqLike[T, Repr]
with ParIterableLike[T, Repr, Sequential] {
self =>
-
+
type SuperParIterator = IterableSplitter[T]
/** A more refined version of the iterator found in the `ParallelIterable` trait,
@@ -330,7 +330,6 @@ self =>
def apply(idx: Int) = self(idx)
override def seq = self.seq.view
def splitter = self.splitter
- override def isEmpty = size == 0
}
/* tasks */
diff --git a/src/library/scala/concurrent/Future.scala b/src/library/scala/concurrent/Future.scala
index 320a4f22b8..4b9e74708d 100644
--- a/src/library/scala/concurrent/Future.scala
+++ b/src/library/scala/concurrent/Future.scala
@@ -522,29 +522,6 @@ trait Future[+T] extends Awaitable[T] {
p.future
}
- /** Creates a new future which holds the result of either this future or `that` future, depending on
- * which future was completed first.
- *
- * $nonDeterministic
- *
- * Example:
- * {{{
- * val f = future { sys.error("failed") }
- * val g = future { 5 }
- * val h = f either g
- * await(h, 0) // evaluates to either 5 or throws a runtime exception
- * }}}
- */
- def either[U >: T](that: Future[U]): Future[U] = {
- val p = Promise[U]()
- val completePromise: PartialFunction[Try[U], _] = { case result => p tryComplete result }
-
- this onComplete completePromise
- that onComplete completePromise
-
- p.future
- }
-
}
diff --git a/src/library/scala/concurrent/package.scala b/src/library/scala/concurrent/package.scala
index f7c732b851..3e849f1722 100644
--- a/src/library/scala/concurrent/package.scala
+++ b/src/library/scala/concurrent/package.scala
@@ -29,13 +29,12 @@ package object concurrent {
*/
def future[T](body: =>T)(implicit execctx: ExecutionContext): Future[T] = Future[T](body)
- /** Creates a promise object which can be completed with a value.
+ /** Creates a promise object which can be completed with a value or an exception.
*
* @tparam T the type of the value in the promise
- * @param execctx the execution context on which the promise is created on
* @return the newly created `Promise` object
*/
- def promise[T]()(implicit execctx: ExecutionContext): Promise[T] = Promise[T]()
+ def promise[T](): Promise[T] = Promise[T]()
/** Used to designate a piece of code which potentially blocks, allowing the current [[BlockContext]] to adjust
* the runtime's behavior.
diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala
index 554e7848c7..8c18809ad6 100644
--- a/src/partest/scala/tools/partest/DirectTest.scala
+++ b/src/partest/scala/tools/partest/DirectTest.scala
@@ -8,6 +8,7 @@ package scala.tools.partest
import scala.tools.nsc._
import io.Directory
import util.{BatchSourceFile, CommandLineParser}
+import reporters.{Reporter, ConsoleReporter}
/** A class for testing code which is embedded as a string.
* It allows for more complete control over settings, compiler
@@ -38,9 +39,12 @@ abstract class DirectTest extends App {
// new compiler
def newCompiler(args: String*): Global = {
val settings = newSettings((CommandLineParser tokenize ("-d \"" + testOutput.path + "\" " + extraSettings)) ++ args.toList)
- if (settings.Yrangepos.value) new Global(settings) with interactive.RangePositions
- else new Global(settings)
+ if (settings.Yrangepos.value) new Global(settings, reporter(settings)) with interactive.RangePositions
+ else new Global(settings, reporter(settings))
}
+
+ def reporter(settings: Settings): Reporter = new ConsoleReporter(settings)
+
def newSources(sourceCodes: String*) = sourceCodes.toList.zipWithIndex map {
case (src, idx) => new BatchSourceFile("newSource" + (idx + 1), src)
}
diff --git a/src/partest/scala/tools/partest/StoreReporterDirectTest.scala b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala
new file mode 100644
index 0000000000..7f3604c86c
--- /dev/null
+++ b/src/partest/scala/tools/partest/StoreReporterDirectTest.scala
@@ -0,0 +1,15 @@
+package scala.tools.partest
+
+import scala.tools.nsc.Settings
+import scala.tools.nsc.reporters.StoreReporter
+import scala.collection.mutable
+
+trait StoreReporterDirectTest extends DirectTest {
+ lazy val storeReporter: StoreReporter = new scala.tools.nsc.reporters.StoreReporter()
+
+ /** Discards all but the first message issued at a given position. */
+ def filteredInfos: Seq[storeReporter.Info] = storeReporter.infos.groupBy(_.pos).map(_._2.head).toList
+
+ /** Hook into [[scala.tools.partest.DirectTest]] to install the custom reporter */
+ override def reporter(settings: Settings) = storeReporter
+}
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 9fe443bf50..1df91a67b0 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -19,9 +19,26 @@ trait StdAttachments {
def setPos(newpos: Position): this.type = { pos = newpos; this }
}
+ /** When present, indicates that the host `Ident` has been created from a backquoted identifier.
+ */
case object BackquotedIdentifierAttachment
+ /** Stores the trees that give rise to a refined type to be used in reification.
+ * Unfortunately typed `CompoundTypeTree` is lacking essential info, and the reifier cannot use `CompoundTypeTree.tpe`.
+ * Therefore we need this hack (see `Reshape.toPreTyperTypeTree` for a detailed explanation).
+ */
case class CompoundTypeTreeOriginalAttachment(parents: List[Tree], stats: List[Tree])
+ /** Is added by the macro engine to the results of macro expansions.
+ * Stores the original expandee as it entered the `macroExpand` function.
+ */
case class MacroExpansionAttachment(original: Tree)
+
+ /** When present, suppresses macro expansion for the host.
+ * This is occasionally necessary, e.g. to prohibit eta-expansion of macros.
+ *
+ * Does not affect expandability of child nodes, there's context.withMacrosDisabled for that
+ * (but think thrice before using that API - see the discussion at https://github.com/scala/scala/pull/1639).
+ */
+ case object SuppressMacroExpansionAttachment
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 9254cc9ac9..a27afe9dfd 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -79,7 +79,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isImplementationArtifact: Boolean = (this hasFlag BRIDGE) || (this hasFlag VBRIDGE) || (this hasFlag ARTIFACT)
def isJava: Boolean = isJavaDefined
def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable
- def isVar: Boolean = isTerm && !isModule && !isMethod && isMutable
+ def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable
def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
@@ -423,9 +423,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* failure to the point when that name is used for something, which is
* often to the point of never.
*/
- def newStubSymbol(name: Name): Symbol = name match {
- case n: TypeName => new StubClassSymbol(this, n)
- case _ => new StubTermSymbol(this, name.toTermName)
+ def newStubSymbol(name: Name, missingMessage: String): Symbol = name match {
+ case n: TypeName => new StubClassSymbol(this, n, missingMessage)
+ case _ => new StubTermSymbol(this, name.toTermName, missingMessage)
}
@deprecated("Use the other signature", "2.10.0")
@@ -1349,6 +1349,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
+ /** Raises a `MissingRequirementError` if this symbol is a `StubSymbol` */
+ def failIfStub() {}
+
/** Initialize the symbol */
final def initialize: this.type = {
if (!isInitialized) info
@@ -3105,14 +3108,18 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
}
trait StubSymbol extends Symbol {
- protected def stubWarning = {
- val from = if (associatedFile == null) "" else s" - referenced from ${associatedFile.canonicalPath}"
- s"$kindString $nameString$locationString$from (a classfile may be missing)"
- }
+ protected def missingMessage: String
+
+ /** Fail the stub by throwing a [[scala.reflect.internal.MissingRequirementError]]. */
+ override final def failIfStub() = {MissingRequirementError.signal(missingMessage)} //
+
+ /** Fail the stub by reporting an error to the reporter, setting the IS_ERROR flag
+ * on this symbol, and returning the dummy value `alt`.
+ */
private def fail[T](alt: T): T = {
// Avoid issuing lots of redundant errors
if (!hasFlag(IS_ERROR)) {
- globalError(s"bad symbolic reference to " + stubWarning)
+ globalError(missingMessage)
if (settings.debug.value)
(new Throwable).printStackTrace
@@ -3129,12 +3136,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def rawInfo = fail(NoType)
override def companionSymbol = fail(NoSymbol)
- locally {
- debugwarn("creating stub symbol for " + stubWarning)
- }
+ debugwarn("creating stub symbol to defer error: " + missingMessage)
}
- class StubClassSymbol(owner0: Symbol, name0: TypeName) extends ClassSymbol(owner0, owner0.pos, name0) with StubSymbol
- class StubTermSymbol(owner0: Symbol, name0: TermName) extends TermSymbol(owner0, owner0.pos, name0) with StubSymbol
+ class StubClassSymbol(owner0: Symbol, name0: TypeName, protected val missingMessage: String) extends ClassSymbol(owner0, owner0.pos, name0) with StubSymbol
+ class StubTermSymbol(owner0: Symbol, name0: TermName, protected val missingMessage: String) extends TermSymbol(owner0, owner0.pos, name0) with StubSymbol
trait FreeSymbol extends Symbol {
def origin: String
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 38e55a3c01..8ad15f37e4 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -245,6 +245,68 @@ abstract class TreeInfo {
isSelfConstrCall(tree1) || isSuperConstrCall(tree1)
}
+ /**
+ * Does this tree represent an irrefutable pattern match
+ * in the position `for { <tree> <- expr }` based only
+ * on information at the `parser` phase? To qualify, there
+ * may be no subtree that will be interpreted as a
+ * Stable Identifier Pattern.
+ *
+ * For instance:
+ *
+ * {{{
+ * foo @ (bar, (baz, quux))
+ * }}}
+ *
+ * is a variable pattern; if the structure matches,
+ * then the remainder is inevitable.
+ *
+ * The following are not variable patterns.
+ *
+ * {{{
+ * foo @ (bar, (`baz`, quux)) // back quoted ident, not at top level
+ * foo @ (bar, Quux) // UpperCase ident, not at top level
+ * }}}
+ *
+ * If the pattern is a simple identifier, it is always
+ * a variable pattern. For example, the following
+ * introduce new bindings:
+ *
+ * {{{
+ * for { X <- xs } yield X
+ * for { `backquoted` <- xs } yield `backquoted`
+ * }}}
+ *
+ * Note that this differs from a case clause:
+ *
+ * {{{
+ * object X
+ * scrut match {
+ * case X => // case _ if scrut == X
+ * }
+ * }}}
+ *
+ * Background: [[https://groups.google.com/d/msg/scala-internals/qwa_XOw_7Ks/IktkeTBYqg0J]]
+ *
+ */
+ def isVarPatternDeep(tree: Tree): Boolean = {
+ def isVarPatternDeep0(tree: Tree): Boolean = {
+ tree match {
+ case Bind(name, pat) => isVarPatternDeep0(pat)
+ case Ident(name) => isVarPattern(tree)
+ case Apply(sel, args) =>
+ ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName)
+ && (args forall isVarPatternDeep0)
+ )
+ case _ => false
+ }
+ }
+ tree match {
+ case Ident(name) => true
+ case _ => isVarPatternDeep0(tree)
+ }
+ }
+
/** Is tree a variable pattern? */
def isVarPattern(pat: Tree): Boolean = pat match {
case x: Ident => !x.isBackquoted && nme.isVariableName(x.name)
@@ -330,24 +392,6 @@ abstract class TreeInfo {
case _ => false
}
- /** Is this tree comprised of nothing but identifiers,
- * but possibly in bindings or tuples? For instance
- *
- * foo @ (bar, (baz, quux))
- *
- * is a variable pattern; if the structure matches,
- * then the remainder is inevitable.
- */
- def isVariablePattern(tree: Tree): Boolean = tree match {
- case Bind(name, pat) => isVariablePattern(pat)
- case Ident(name) => true
- case Apply(sel, args) =>
- ( isReferenceToScalaMember(sel, TupleClass(args.size).name.toTermName)
- && (args forall isVariablePattern)
- )
- case _ => false
- }
-
/** Is this argument node of the form <expr> : _* ?
*/
def isWildcardStarArg(tree: Tree): Boolean = tree match {
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 74bde132cb..b2158de9ec 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -482,6 +482,10 @@ trait Trees extends api.Trees { self: SymbolTable =>
case class TypeTree() extends TypTree with TypeTreeContextApi {
private var orig: Tree = null
+ /** Was this type tree originally empty? That is, does it now contain
+ * an inferred type that must be forgotten in `resetAttrs` to
+ * enable retyping.
+ */
private[scala] var wasEmpty: Boolean = false
override def symbol = typeTreeSymbol(this) // if (tpe == null) null else tpe.typeSymbol
@@ -502,6 +506,15 @@ trait Trees extends api.Trees { self: SymbolTable =>
wasEmpty = isEmpty
setType(tp)
}
+
+ override private[scala] def copyAttrs(tree: Tree) = {
+ super.copyAttrs(tree)
+ tree match {
+ case other: TypeTree => wasEmpty = other.wasEmpty // SI-6648 Critical for correct operation of `resetAttrs`.
+ case _ =>
+ }
+ this
+ }
}
object TypeTree extends TypeTreeExtractor
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 6df6ed4417..0c4cda8313 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -1398,7 +1398,12 @@ trait Types extends api.Types { self: SymbolTable =>
/** A class for this-types of the form <sym>.this.type
*/
abstract case class ThisType(sym: Symbol) extends SingletonType with ThisTypeApi {
- assert(sym.isClass, sym)
+ if (!sym.isClass) {
+ // SI-6640 allow StubSymbols to reveal what's missing from the classpath before we trip the assertion.
+ sym.failIfStub()
+ assert(false, sym)
+ }
+
//assert(sym.isClass && !sym.isModuleClass || sym.isRoot, sym)
override def isTrivial: Boolean = sym.isPackageClass
override def isNotNull = true
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 43b982a8a4..f3a5053a91 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -20,7 +20,7 @@ import scala.annotation.switch
/** @author Martin Odersky
* @version 1.0
*/
-abstract class UnPickler /*extends scala.reflect.generic.UnPickler*/ {
+abstract class UnPickler {
val global: SymbolTable
import global._
@@ -233,7 +233,12 @@ abstract class UnPickler /*extends scala.reflect.generic.UnPickler*/ {
// (4) Call the mirror's "missing" hook.
adjust(mirrorThatLoaded(owner).missingHook(owner, name)) orElse {
// (5) Create a stub symbol to defer hard failure a little longer.
- owner.newStubSymbol(name)
+ val missingMessage =
+ s"""|bad symbolic reference. A signature in $filename refers to ${name.longString}
+ |in ${owner.kindString} ${owner.fullName} which is not available.
+ |It may be completely missing from the current classpath, or the version on
+ |the classpath might be incompatible with the version used when compiling $filename.""".stripMargin
+ owner.newStubSymbol(name, missingMessage)
}
}
}
@@ -827,11 +832,6 @@ abstract class UnPickler /*extends scala.reflect.generic.UnPickler*/ {
protected def errorBadSignature(msg: String) =
throw new RuntimeException("malformed Scala signature of " + classRoot.name + " at " + readIndex + "; " + msg)
- protected def errorMissingRequirement(name: Name, owner: Symbol): Symbol =
- mirrorThatLoaded(owner).missingHook(owner, name) orElse MissingRequirementError.signal(
- s"bad reference while unpickling $filename: ${name.longString} not found in ${owner.tpe.widen}"
- )
-
def inferMethodAlternative(fun: Tree, argtpes: List[Type], restpe: Type) {} // can't do it; need a compiler for that.
def newLazyTypeRef(i: Int): LazyType = new LazyTypeRef(i)
diff --git a/test/files/neg/t5148.check b/test/files/neg/t5148.check
index 6edfdf2b1e..25107c4dbe 100644
--- a/test/files/neg/t5148.check
+++ b/test/files/neg/t5148.check
@@ -1,3 +1,9 @@
-error: bad symbolic reference to value global in class IMain - referenced from t5148.scala (a classfile may be missing)
-error: bad symbolic reference to value memberHandlers in class IMain - referenced from t5148.scala (a classfile may be missing)
+error: bad symbolic reference. A signature in Imports.class refers to term global
+in class scala.tools.nsc.interpreter.IMain which is not available.
+It may be completely missing from the current classpath, or the version on
+the classpath might be incompatible with the version used when compiling Imports.class.
+error: bad symbolic reference. A signature in Imports.class refers to term memberHandlers
+in class scala.tools.nsc.interpreter.IMain which is not available.
+It may be completely missing from the current classpath, or the version on
+the classpath might be incompatible with the version used when compiling Imports.class.
two errors found
diff --git a/test/files/neg/t6357.check b/test/files/neg/t6357.check
new file mode 100644
index 0000000000..a534d1439a
--- /dev/null
+++ b/test/files/neg/t6357.check
@@ -0,0 +1,4 @@
+t6357.scala:3: error: value class may not be a local class
+ final class Y(val j: Int) extends AnyVal
+ ^
+one error found
diff --git a/test/files/neg/t6357.scala b/test/files/neg/t6357.scala
new file mode 100644
index 0000000000..47f5629638
--- /dev/null
+++ b/test/files/neg/t6357.scala
@@ -0,0 +1,6 @@
+object K {
+ def q = {
+ final class Y(val j: Int) extends AnyVal
+ 3
+ }
+}
diff --git a/test/files/neg/t6663.check b/test/files/neg/t6663.check
new file mode 100644
index 0000000000..aa4faa4a46
--- /dev/null
+++ b/test/files/neg/t6663.check
@@ -0,0 +1,6 @@
+t6663.scala:16: error: type mismatch;
+ found : String
+ required: Int
+ var v = new C(42).foo[String].get :Int
+ ^
+one error found
diff --git a/test/files/neg/t6663.scala b/test/files/neg/t6663.scala
new file mode 100644
index 0000000000..4a358dfbc5
--- /dev/null
+++ b/test/files/neg/t6663.scala
@@ -0,0 +1,19 @@
+import language.dynamics
+
+class C(v: Any) extends Dynamic {
+ def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T])
+ def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T])
+}
+
+object Test extends App {
+ // this should be converted to
+ // C(42).selectDynamic[String]("foo").get
+ // causing a compile error.
+
+ // but, before fixing SI-6663, became
+ // C(42).selectDynamic("foo").get, ignoring
+ // the [String] type parameter
+ var v = new C(42).foo[String].get :Int
+ println(v)
+}
+
diff --git a/test/files/pos/t6551.scala b/test/files/pos/t6551.scala
new file mode 100644
index 0000000000..fb68663809
--- /dev/null
+++ b/test/files/pos/t6551.scala
@@ -0,0 +1,13 @@
+import language.dynamics
+
+object Test {
+ def main(args: Array[String]) {
+ class Lenser[T] extends Dynamic {
+ def selectDynamic(propName: String) = ???
+ }
+
+ def lens[T] = new Lenser[T]
+
+ val qq = lens[String]
+ }
+}
diff --git a/test/files/pos/t6624.scala b/test/files/pos/t6624.scala
new file mode 100644
index 0000000000..1a92b92d53
--- /dev/null
+++ b/test/files/pos/t6624.scala
@@ -0,0 +1,28 @@
+sealed trait KList[+M[_]]
+
+case class KCons[M[_], +T <: KList[M]](
+ tail: T
+) extends KList[M]
+
+case class KNil[M[_]]() extends KList[M]
+
+object Test {
+ val klist: KCons[Option, KCons[Option, KCons[Option, KNil[Nothing]]]] = ???
+
+ // crashes with
+ // "Exception in thread "main" scala.reflect.internal.Types$TypeError: value _1 is not a member
+ // of KCons[Option,KCons[Option,KNil[Nothing]]]"
+ klist match {
+ case KCons(KCons(KCons(_))) =>
+ }
+
+ // fails with a similar message as an error, rather than a crash.
+ klist match {
+ case KCons(KCons(_)) =>
+ }
+
+ // succeeds
+ klist match {
+ case KCons(_) =>
+ }
+} \ No newline at end of file
diff --git a/test/files/pos/t6648.scala b/test/files/pos/t6648.scala
new file mode 100644
index 0000000000..9593ebfee9
--- /dev/null
+++ b/test/files/pos/t6648.scala
@@ -0,0 +1,24 @@
+abstract class Node extends NodeSeq
+trait NodeSeq extends Seq[Node]
+object NodeSeq {
+ implicit def seqToNodeSeq(ns: Seq[Node]): NodeSeq = ???
+ def foo[B, That](f: Seq[B])(implicit bf: scala.collection.generic.CanBuildFrom[Seq[Int], B, That]): That = ???
+}
+
+class Transformer {
+ def apply(nodes: Any): Any = ???
+}
+
+object transformer1 extends Transformer {
+ // Adding explicit type arguments, or making the impilcit view
+ // seqToNodeSeq explicit avoids the crash
+ NodeSeq.foo {
+ // These both avoid the crash:
+ // val t = new Transformer {}; t.apply(null)
+ // new Transformer().apply(null)
+ new Transformer {}.apply(null)
+
+ null: NodeSeq
+ }: NodeSeq
+}
+
diff --git a/test/files/run/rawstrings.check b/test/files/run/rawstrings.check
index 36e63594df..2b6c40725a 100644
--- a/test/files/run/rawstrings.check
+++ b/test/files/run/rawstrings.check
@@ -1 +1 @@
-[\n\t'"$]
+[\n\t'"$\n]
diff --git a/test/files/run/rawstrings.scala b/test/files/run/rawstrings.scala
index 9df64f6625..b4d6e0c40a 100644
--- a/test/files/run/rawstrings.scala
+++ b/test/files/run/rawstrings.scala
@@ -1,3 +1,3 @@
object Test extends App {
- println(raw"[\n\t'${'"'}$$]")
+ println(raw"[\n\t'${'"'}$$\n]")
}
diff --git a/test/files/run/showraw_aliases.check b/test/files/run/showraw_aliases.check
index 1838bf9bec..aebd354031 100644
--- a/test/files/run/showraw_aliases.check
+++ b/test/files/run/showraw_aliases.check
@@ -1,2 +1,2 @@
-Block(List(Import(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), List(ImportSelector(newTermName("universe"), 52, newTermName("ru"), 64)))), Select(Select(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), scala.reflect.runtime.package), [newTermName("universe") aka newTermName("ru")]))
-Block(List(Import(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), List(ImportSelector(newTermName("universe"), 52, newTermName("ru"), 64)))), Select(Select(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), scala.reflect.runtime.package#<id>), [newTermName("universe")#<id> aka newTermName("ru")]))
+Block(List(Import(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), List(ImportSelector(newTermName("universe"), <offset>, newTermName("ru"), <offset>)))), Select(Select(Select(Select(Ident(scala), scala.reflect), scala.reflect.runtime), scala.reflect.runtime.package), [newTermName("universe") aka newTermName("ru")]))
+Block(List(Import(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), List(ImportSelector(newTermName("universe"), <offset>, newTermName("ru"), <offset>)))), Select(Select(Select(Select(Ident(scala#<id>), scala.reflect#<id>), scala.reflect.runtime#<id>), scala.reflect.runtime.package#<id>), [newTermName("universe")#<id> aka newTermName("ru")]))
diff --git a/test/files/run/showraw_aliases.scala b/test/files/run/showraw_aliases.scala
index 3a68ca37b2..65b4fcb1cd 100644
--- a/test/files/run/showraw_aliases.scala
+++ b/test/files/run/showraw_aliases.scala
@@ -9,7 +9,9 @@ object Test extends App {
""")
val ttree = tb.typeCheck(tree)
- def stabilize(s: String) = """#\d+""".r.replaceAllIn(s, "#<id>")
- println(showRaw(ttree))
+ def stabilizeIds(s: String) = """#\d+""".r.replaceAllIn(s, "#<id>")
+ def stabilizePositions(s: String) = """\d+""".r.replaceAllIn(s, "<offset>")
+ def stabilize(s: String) = stabilizePositions(stabilizeIds(s))
+ println(stabilize(showRaw(ttree)))
println(stabilize(showRaw(ttree, printIds = true)))
} \ No newline at end of file
diff --git a/test/files/run/t6023.check b/test/files/run/t6023.check
new file mode 100644
index 0000000000..ee93565234
--- /dev/null
+++ b/test/files/run/t6023.check
@@ -0,0 +1,12 @@
+{
+ abstract trait Foo extends AnyRef {
+ <stable> <accessor> def a: Int
+ };
+ ()
+}
+{
+ abstract trait Foo extends AnyRef {
+ <stable> <accessor> def a: Int
+ };
+ ()
+}
diff --git a/test/files/run/t6023.scala b/test/files/run/t6023.scala
new file mode 100644
index 0000000000..07af3685a5
--- /dev/null
+++ b/test/files/run/t6023.scala
@@ -0,0 +1,17 @@
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+import scala.tools.reflect.ToolBox
+
+object Test extends App {
+ // test 1: reify
+ val tree = reify{ trait Foo { val a: Int } }.tree
+ println(tree.toString)
+
+ // test 2: import and typecheck
+ val toolbox = cm.mkToolBox()
+ val ttree = toolbox.typeCheck(tree)
+ println(ttree.toString)
+
+ // test 3: import and compile
+ toolbox.eval(tree)
+}
diff --git a/test/files/run/t6440.check b/test/files/run/t6440.check
index b5684daee4..69c253eab4 100644
--- a/test/files/run/t6440.check
+++ b/test/files/run/t6440.check
@@ -1 +1,4 @@
-Stream((), ?)
+pos: source-newSource1,line-9,offset=109 bad symbolic reference. A signature in U.class refers to term pack1
+in package <root> which is not available.
+It may be completely missing from the current classpath, or the version on
+the classpath might be incompatible with the version used when compiling U.class. ERROR
diff --git a/test/files/run/t6440.scala b/test/files/run/t6440.scala
index 2b690f31e1..5a3a4150d9 100644
--- a/test/files/run/t6440.scala
+++ b/test/files/run/t6440.scala
@@ -1,7 +1,48 @@
-object Test {
+import scala.tools.partest._
+import java.io.File
- def main(args: Array[String]): Unit = {
- println(Stream.continually(()).filterNot(_ => false).take(2))
+object Test extends StoreReporterDirectTest {
+ def code = ???
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
}
+ def library1 = """
+ package pack1
+ trait T
+ """
+
+ def library2 = """
+ package pack2
+ trait U extends pack1.T
+ """
+
+ def app = """
+ package pack3
+ object X {
+ trait U
+ }
+ import X._
+ import pack2._
+
+ trait V extends U
+ """
+
+ def show(): Unit = {
+ Seq(library1, library2) foreach compileCode
+ assert(filteredInfos.isEmpty, filteredInfos)
+
+ // blow away the entire package
+ val pack1 = new File(testOutput.path, "pack1")
+ val tClass = new File(pack1, "T.class")
+ assert(tClass.exists)
+ assert(tClass.delete())
+ assert(pack1.delete())
+
+ // bad symbolic reference error expected (but no stack trace!)
+ compileCode(app)
+ println(filteredInfos.mkString("\n"))
+ }
}
diff --git a/test/files/run/t6440b.check b/test/files/run/t6440b.check
new file mode 100644
index 0000000000..9771ce5efb
--- /dev/null
+++ b/test/files/run/t6440b.check
@@ -0,0 +1,4 @@
+pos: NoPosition bad symbolic reference. A signature in U.class refers to type T
+in package pack1 which is not available.
+It may be completely missing from the current classpath, or the version on
+the classpath might be incompatible with the version used when compiling U.class. ERROR
diff --git a/test/files/run/t6440b.scala b/test/files/run/t6440b.scala
new file mode 100644
index 0000000000..974aca2844
--- /dev/null
+++ b/test/files/run/t6440b.scala
@@ -0,0 +1,61 @@
+import scala.tools.partest._
+import java.io.File
+
+object Test extends StoreReporterDirectTest {
+ def code = ???
+
+ def compileCode(code: String) = {
+ val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(code)
+ }
+
+ def library1 = """
+ package pack1
+ trait T
+ class U {
+ def t = new T {}
+ def one = 1
+ }
+ """
+
+ def library2 = """
+ package pack2
+ object V {
+ def u = new pack1.U
+ }
+ """
+
+ def app1 = """
+ package pack3
+ object Test {
+ pack2.V.u.one // okay
+ }
+ """
+
+ def app2 = """
+ package pack3
+ object Test {
+ pack2.V.u.t // we have to fail if T.class is misisng
+ }
+ """
+
+ def show(): Unit = {
+ compileCode(library1)
+ val pack1 = new File(testOutput.path, "pack1")
+ val tClass = new File(pack1, "T.class")
+ assert(tClass.exists)
+ assert(tClass.delete())
+
+ // allowed to compile, no direct reference to `T`
+ compileCode(library2)
+ assert(filteredInfos.isEmpty, filteredInfos)
+
+ // allowed to compile, no direct reference to `T`
+ compileCode(app1)
+ assert(filteredInfos.isEmpty, filteredInfos)
+
+ // bad symbolic reference error expected (but no stack trace!)
+ compileCode(app2)
+ println(filteredInfos.mkString("\n"))
+ }
+}
diff --git a/test/files/run/t6628.check b/test/files/run/t6628.check
new file mode 100644
index 0000000000..bb101b641b
--- /dev/null
+++ b/test/files/run/t6628.check
@@ -0,0 +1,2 @@
+true
+true
diff --git a/test/files/run/t6628.scala b/test/files/run/t6628.scala
new file mode 100644
index 0000000000..84524a7a35
--- /dev/null
+++ b/test/files/run/t6628.scala
@@ -0,0 +1,11 @@
+object Test {
+ def coll = new Traversable[String] {
+ override def foreach[U](f:String=>U) { f("1") }
+ }
+ val dropped = coll.view drop 1
+
+ def main(args: Array[String]): Unit = {
+ println(dropped.isEmpty)
+ println(dropped.force.isEmpty)
+ }
+}
diff --git a/test/files/run/t6632.check b/test/files/run/t6632.check
new file mode 100644
index 0000000000..1f084b1dac
--- /dev/null
+++ b/test/files/run/t6632.check
@@ -0,0 +1,3 @@
+java.lang.IndexOutOfBoundsException: -1
+java.lang.IndexOutOfBoundsException: -2
+java.lang.IndexOutOfBoundsException: -3
diff --git a/test/files/run/t6632.scala b/test/files/run/t6632.scala
new file mode 100644
index 0000000000..c1c8d4abe0
--- /dev/null
+++ b/test/files/run/t6632.scala
@@ -0,0 +1,29 @@
+object Test extends App {
+ import collection.mutable.ListBuffer
+
+ def newLB = ListBuffer('a, 'b, 'c, 'd, 'e)
+
+ val lb0 = newLB
+
+ try {
+ lb0.insert(-1, 'x)
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+
+ val lb1 = newLB
+
+ try {
+ lb1.insertAll(-2, Array('x, 'y, 'z))
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+
+ val lb2 = newLB
+
+ try {
+ lb2.update(-3, 'u)
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6633.check b/test/files/run/t6633.check
new file mode 100644
index 0000000000..1ff8cdbc44
--- /dev/null
+++ b/test/files/run/t6633.check
@@ -0,0 +1,3 @@
+java.lang.IndexOutOfBoundsException: 9
+replStringOf OK
+length OK
diff --git a/test/files/run/t6633.scala b/test/files/run/t6633.scala
new file mode 100644
index 0000000000..bd993c8d88
--- /dev/null
+++ b/test/files/run/t6633.scala
@@ -0,0 +1,33 @@
+object Test extends App {
+ import collection.mutable.ListBuffer
+
+ def newLB = ListBuffer('a, 'b, 'c, 'd, 'e)
+
+ val lb0 = newLB
+
+ try {
+ lb0.insert(9, 'x)
+ } catch {
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+
+ val lb1 = newLB
+
+ try {
+ lb1.insert(9, 'x)
+ } catch {
+ case ex: IndexOutOfBoundsException =>
+ }
+
+ val replStr = scala.runtime.ScalaRunTime.replStringOf(lb1, 100)
+ if (replStr == "ListBuffer('a, 'b, 'c, 'd, 'e)\n")
+ println("replStringOf OK")
+ else
+ println("replStringOf FAILED: " + replStr)
+
+ val len = lb1.length
+ if (len == 5)
+ println("length OK")
+ else
+ println("length FAILED: " + len)
+} \ No newline at end of file
diff --git a/test/files/run/t6634.check b/test/files/run/t6634.check
new file mode 100644
index 0000000000..f6cbb30c67
--- /dev/null
+++ b/test/files/run/t6634.check
@@ -0,0 +1,31 @@
+Trying lb0 ...
+Checking ...
+String OK.
+Length OK.
+
+Trying lb1 ...
+Checking ...
+String OK.
+Length OK.
+
+Trying lb2 ...
+Checking ...
+String OK.
+Length OK.
+
+Trying lb3 ...
+Checking ...
+String OK.
+Length OK.
+
+Trying lb4 ...
+Checking ...
+String OK.
+Length OK.
+
+Trying lb5 ...
+java.lang.IllegalArgumentException: removing negative number (-1) of elements
+Checking ...
+String OK.
+Length OK.
+
diff --git a/test/files/run/t6634.scala b/test/files/run/t6634.scala
new file mode 100644
index 0000000000..759e6d519d
--- /dev/null
+++ b/test/files/run/t6634.scala
@@ -0,0 +1,80 @@
+import collection.mutable.ListBuffer
+
+object Test extends App {
+ def newLB = ListBuffer('a, 'b, 'c, 'd, 'e)
+
+ val lb0 = newLB
+ println("Trying lb0 ...")
+ try {
+ lb0.remove(5, 0)
+ } catch {
+ // Not thrown in 2.10, will be thrown in 2.11
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+ checkNotCorrupted(lb0)
+
+ val lb1 = newLB
+ println("Trying lb1 ...")
+ try {
+ lb1.remove(6, 6)
+ } catch {
+ // Not thrown in 2.10, will be thrown in 2.11
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+ checkNotCorrupted(lb1)
+
+ val lb2 = newLB
+ println("Trying lb2 ...")
+ try {
+ lb2.remove(99, 6)
+ } catch {
+ // Not thrown in 2.10, will be thrown in 2.11
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+ checkNotCorrupted(lb2)
+
+ val lb3 = newLB
+ println("Trying lb3 ...")
+ try {
+ lb3.remove(1, 9)
+ } catch {
+ // Not thrown in 2.10, will be thrown in 2.11
+ case ex: IllegalArgumentException => println(ex)
+ }
+ checkNotCorrupted(lb3, "ListBuffer('a)", 1)
+
+ val lb4 = newLB
+ println("Trying lb4 ...")
+ try {
+ lb4.remove(-1, 1)
+ } catch {
+ // Not thrown in 2.10, will be thrown in 2.11
+ case ex: IndexOutOfBoundsException => println(ex)
+ }
+ checkNotCorrupted(lb4, "ListBuffer('b, 'c, 'd, 'e)", 4)
+
+ val lb5 = newLB
+ println("Trying lb5 ...")
+ try {
+ lb5.remove(1, -1)
+ } catch {
+ case ex: IllegalArgumentException => println(ex)
+ }
+ checkNotCorrupted(lb5)
+
+ // buffer should neither be changed nor corrupted after calling remove with invalid arguments
+ def checkNotCorrupted(
+ lb: ListBuffer[Symbol],
+ expectedString: String = "ListBuffer('a, 'b, 'c, 'd, 'e)",
+ expectedLength: Int = 5) = {
+ println("Checking ...")
+ val replStr = scala.runtime.ScalaRunTime.replStringOf(lb, 100)
+ if (replStr == expectedString + "\n") println("String OK.")
+ else println("!!! replStringOf FAILED: " + replStr)
+
+ val len = lb.length
+ if (len == expectedLength) println("Length OK.")
+ else println("!!! length FAILED: " + len)
+ println()
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t6644.scala b/test/files/run/t6644.scala
new file mode 100644
index 0000000000..b8b36f957c
--- /dev/null
+++ b/test/files/run/t6644.scala
@@ -0,0 +1,8 @@
+class Testable(val c: String) extends AnyVal {
+ def matching(cases: Boolean*) = cases contains true
+}
+
+object Test extends App {
+ assert(new Testable("").matching(true, false))
+}
+
diff --git a/test/files/run/t6646.check b/test/files/run/t6646.check
new file mode 100644
index 0000000000..b0b7ad32f3
--- /dev/null
+++ b/test/files/run/t6646.check
@@ -0,0 +1,5 @@
+Found NotNull
+Found lower
+Found 2
+A single ident is always a pattern
+A single ident is always a pattern
diff --git a/test/files/run/t6646.scala b/test/files/run/t6646.scala
new file mode 100644
index 0000000000..150b0df11e
--- /dev/null
+++ b/test/files/run/t6646.scala
@@ -0,0 +1,19 @@
+sealed trait ColumnOption
+case object NotNull extends ColumnOption
+case object PrimaryKey extends ColumnOption
+case object lower extends ColumnOption
+
+object Test {
+ def main(args: Array[String]) {
+ val l = List(PrimaryKey, NotNull, lower)
+
+ // withFilter must be generated in these
+ for (option @ NotNull <- l) println("Found " + option)
+ for (option @ `lower` <- l) println("Found " + option)
+ for ((`lower`, i) <- l.zipWithIndex) println("Found " + i)
+
+ // no withFilter
+ for (X <- List("A single ident is always a pattern")) println(X)
+ for (`x` <- List("A single ident is always a pattern")) println(`x`)
+ }
+}
diff --git a/test/files/run/t6663.check b/test/files/run/t6663.check
new file mode 100644
index 0000000000..d81cc0710e
--- /dev/null
+++ b/test/files/run/t6663.check
@@ -0,0 +1 @@
+42
diff --git a/test/files/run/t6663.scala b/test/files/run/t6663.scala
new file mode 100644
index 0000000000..6818d286d9
--- /dev/null
+++ b/test/files/run/t6663.scala
@@ -0,0 +1,17 @@
+import language.dynamics
+
+class C(v: Any) extends Dynamic {
+ def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T])
+ def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T])
+}
+
+object Test extends App {
+ // this should be converted to
+ // C(42).selectDynamic[Int]("foo").get
+ // but, before fixing SI-6663, became
+ // C(42).selectDynamic[Nothing]("foo").get
+ // leading to a ClassCastException
+ var v = new C(42).foo[Int].get
+ println(v)
+}
+
diff --git a/test/files/run/t6673.check b/test/files/run/t6673.check
new file mode 100644
index 0000000000..ef2aa551dc
--- /dev/null
+++ b/test/files/run/t6673.check
@@ -0,0 +1 @@
+List(x)
diff --git a/test/files/run/t6673.scala b/test/files/run/t6673.scala
new file mode 100644
index 0000000000..115bbdf234
--- /dev/null
+++ b/test/files/run/t6673.scala
@@ -0,0 +1,5 @@
+object Test extends App {
+ def foo(f: String => Array[String])(s: String) = f(s)
+ val test = foo(Array(_)) _
+ println(test("x").toList)
+} \ No newline at end of file
diff --git a/test/files/run/t6677.scala b/test/files/run/t6677.scala
new file mode 100644
index 0000000000..e6eaf6a498
--- /dev/null
+++ b/test/files/run/t6677.scala
@@ -0,0 +1,28 @@
+
+class Test {
+ val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror
+ def error {
+ new cm.universe.Traverser // java.lang.VerifyError: (class: Test, method: error signature: ()V) Incompatible object argument for function call
+
+ }
+
+ def okay1 {
+ val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror
+
+ new cm.universe.Traverser
+ }
+
+ def okay2 {
+ val cm: reflect.runtime.universe.Mirror = reflect.runtime.currentMirror
+ val u: reflect.runtime.universe.type = cm.universe
+ new u.Traverser
+ }
+}
+
+object Test {
+ def main(args: Array[String]) {
+ new Test().error
+ new Test().okay1
+ new Test().okay2
+ }
+}
diff --git a/test/files/run/t6677b.scala b/test/files/run/t6677b.scala
new file mode 100644
index 0000000000..e4fe5e3722
--- /dev/null
+++ b/test/files/run/t6677b.scala
@@ -0,0 +1,33 @@
+trait U {
+ trait U1 {
+ class X
+ }
+ type U11 <: U1
+ val u : U11 = null.asInstanceOf[U11]
+}
+trait A extends U
+
+trait B extends U {
+ def foo = ""
+ class U11 extends U1 { class X extends super.X { foo } } // refer to foo to add $outer pointer
+ override val u = new U11
+}
+class C {
+ val ab: A with B = new A with B // `B with A` works.
+
+ def foo {
+ // fails
+ new ab.u.X
+
+ // works:
+ val u = ab.u
+ new u.X
+ }
+}
+object Test {
+ def main(args: Array[String]) {
+ // java.lang.NoSuchMethodError: A.u()LB$U11;
+ // at C.foo(t6677b.scala:23)
+ new C().foo
+ }
+}
diff --git a/test/files/run/t6687.scala b/test/files/run/t6687.scala
new file mode 100644
index 0000000000..ee44e5f0d2
--- /dev/null
+++ b/test/files/run/t6687.scala
@@ -0,0 +1,10 @@
+import scala.reflect.runtime.universe._
+
+class A { lazy val x = 1 }
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ val vars = typeOf[A].members.toList filter (x => x.isTerm && x.asTerm.isVar)
+ assert(vars.isEmpty, vars)
+ }
+}
diff --git a/test/files/run/t6695.scala b/test/files/run/t6695.scala
new file mode 100644
index 0000000000..b527238a51
--- /dev/null
+++ b/test/files/run/t6695.scala
@@ -0,0 +1,18 @@
+object Test extends App {
+ try {
+ Array("a", "b", "c") match {
+ case Array("a", "x", "c") => println("x")
+ case Array("a", "b", "x") => println("a");
+ case Array("a", "d", _*) => println("wrongly positive")
+ }
+ assert(false, "match succeeded")
+ } catch {
+ case _: MatchError => // okay
+ }
+
+ Array("a", "b", "c") match {
+ case Array("a", "x", "c") => println("x")
+ case Array("a", "b", "x") => println("a");
+ case Array("a", "b", _*) => // okay
+ }
+}
diff --git a/test/files/run/t6706.scala b/test/files/run/t6706.scala
new file mode 100644
index 0000000000..905494ca8d
--- /dev/null
+++ b/test/files/run/t6706.scala
@@ -0,0 +1,14 @@
+object Test {
+ var name = "foo" + 1
+ var s1 = Symbol(name)
+ s1 = null
+ System.gc
+ val s2 = Symbol("foo1")
+ name = null
+ System.gc
+ val s3 = Symbol("foo1")
+
+ def main(args: Array[String]): Unit = {
+ assert(s2 eq s3, ((s2, System.identityHashCode(s2), s3, System.identityHashCode(s3))))
+ }
+}
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_lookup.check b/test/files/run/typetags_without_scala_reflect_typetag_lookup.check
index 53df68cfc2..8c558ced60 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_lookup.check
+++ b/test/files/run/typetags_without_scala_reflect_typetag_lookup.check
@@ -1,3 +1,2 @@
-newSource1:9: error: could not find implicit value for evidence parameter of type reflect.runtime.package.universe.TypeTag[Int]
- Library.foo[Int]
- ^
+
+pos: source-newSource1,line-9,offset=466 could not find implicit value for evidence parameter of type reflect.runtime.package.universe.TypeTag[Int] ERROR
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
index e51ecdb180..1fbdc62a1e 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
+++ b/test/files/run/typetags_without_scala_reflect_typetag_lookup.scala
@@ -1,6 +1,6 @@
import scala.tools.partest._
-object Test extends DirectTest {
+object Test extends StoreReporterDirectTest {
def code = ???
def library = """
@@ -32,14 +32,12 @@ object Test extends DirectTest {
}
def show(): Unit = {
- val prevErr = System.err
- val baos = new java.io.ByteArrayOutputStream();
- System.setErr(new java.io.PrintStream(baos));
compileLibrary();
+ println(filteredInfos.mkString("\n"))
+ storeReporter.infos.clear()
compileApp();
- // we should get bad symbolic reference errors, because we're trying to call a method that can't be unpickled
+ // we should get bad symbolic reference errors, because we're trying to use an implicit that can't be unpickled
// but we don't know the number of these errors and their order, so I just ignore them all
- baos.toString.split("\n") filter (!_.startsWith("error: bad symbolic reference")) foreach println
- System.setErr(prevErr)
+ println(filteredInfos.filterNot(_.msg.contains("bad symbolic reference")).mkString("\n"))
}
-} \ No newline at end of file
+}
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check
index 729c0715df..acfecce628 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check
+++ b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.check
@@ -1,3 +1,2 @@
-newSource1:9: error: No Manifest available for App.this.T.
- manifest[T]
- ^
+
+pos: source-newSource1,line-9,offset=479 No Manifest available for App.this.T. ERROR
diff --git a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
index e984127583..6804baa0c3 100644
--- a/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
+++ b/test/files/run/typetags_without_scala_reflect_typetag_manifest_interop.scala
@@ -1,6 +1,7 @@
import scala.tools.partest._
+import scala.tools.nsc.Settings
-object Test extends DirectTest {
+object Test extends StoreReporterDirectTest {
def code = ???
def library = """
@@ -29,18 +30,18 @@ object Test extends DirectTest {
"""
def compileApp() = {
val classpath = List(sys.props("partest.lib"), testOutput.path) mkString sys.props("path.separator")
+ val global = newCompiler("-cp", classpath, "-d", testOutput.path)
compileString(newCompiler("-cp", classpath, "-d", testOutput.path))(app)
+ //global.reporter.ERROR.foreach(println)
}
def show(): Unit = {
- val prevErr = System.err
- val baos = new java.io.ByteArrayOutputStream();
- System.setErr(new java.io.PrintStream(baos));
compileLibrary();
+ println(filteredInfos.mkString("\n"))
+ storeReporter.infos.clear()
compileApp();
// we should get bad symbolic reference errors, because we're trying to use an implicit that can't be unpickled
// but we don't know the number of these errors and their order, so I just ignore them all
- baos.toString.split("\n") filter (!_.startsWith("error: bad symbolic reference")) foreach println
- System.setErr(prevErr)
+ println(filteredInfos.filterNot (_.msg.contains("bad symbolic reference")).mkString("\n"))
}
-} \ No newline at end of file
+}
diff --git a/tools/epfl-publish b/tools/epfl-publish
index de5e17b13f..cdf18823a5 100755
--- a/tools/epfl-publish
+++ b/tools/epfl-publish
@@ -24,7 +24,7 @@ if [[ -z $publish_to ]]; then
else
echo "Publishing nightly build to $publish_to"
# Archive Scala nightly distribution
- rsync -az dists/archives/ "$publish_to/distributions"
+ rsync -az --exclude scala-latest-sources.tgz dists/archives/ "$publish_to/distributions"
# only publish scaladoc nightly for trunk
[[ $version == "master" ]] && rsync -az build/scaladoc/ "$publish_to/docs"
# sbaz