summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala22
-rw-r--r--src/library/scala/collection/immutable/Range.scala147
-rw-r--r--src/library/scala/sys/process/ProcessBuilder.scala40
-rw-r--r--src/library/scala/sys/process/ProcessBuilderImpl.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala173
-rw-r--r--src/reflect/scala/reflect/internal/tpe/FindMembers.scala288
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala31
-rw-r--r--test/files/neg/forgot-interpolator.check5
-rw-r--r--test/files/neg/forgot-interpolator.scala2
-rw-r--r--test/files/neg/t0764b.check63
-rw-r--r--test/files/neg/t0764b.scala64
-rw-r--r--test/files/neg/t7475c.check7
-rw-r--r--test/files/neg/t7475c.scala9
-rw-r--r--test/files/neg/t7475d.check7
-rw-r--r--test/files/neg/t7475e.check4
-rw-r--r--test/files/neg/t7475e.scala12
-rw-r--r--test/files/neg/t7475f.check10
-rw-r--r--test/files/neg/t7475f.scala28
-rw-r--r--test/files/neg/t7507.check2
-rw-r--r--test/files/pos/t1786-counter.scala38
-rw-r--r--test/files/pos/t261-ab.scala9
-rw-r--r--test/files/pos/t261-ba.scala9
-rw-r--r--test/files/pos/t7475a.scala11
-rw-r--r--test/files/pos/t7475b.scala8
-rw-r--r--test/files/pos/t7475d.scala11
-rw-r--r--test/files/pos/t7475e.scala13
-rw-r--r--test/files/presentation/ide-bug-1000531.check2
-rw-r--r--test/files/presentation/ping-pong.check2
-rw-r--r--test/files/presentation/scope-completion-3.check28
-rw-r--r--test/files/presentation/scope-completion-import.check16
-rw-r--r--test/files/presentation/visibility.check3
-rw-r--r--test/files/run/reflection-magicsymbols-invoke.check1
-rw-r--r--test/files/run/reflection-sorted-members.check1
-rw-r--r--test/files/run/t261.check2
-rw-r--r--test/files/run/t261.scala11
-rw-r--r--test/files/run/t7475b.check2
-rw-r--r--test/files/run/t7475b.scala11
-rw-r--r--test/files/run/t7507.scala4
-rw-r--r--test/files/scalacheck/range.scala3
-rw-r--r--test/junit/scala/collection/NumericRangeTest.scala19
-rw-r--r--test/pending/pos/t1786.scala (renamed from test/files/pos/t1786.scala)8
-rw-r--r--test/pending/pos/t5459.scala (renamed from test/files/pos/t5459.scala)0
43 files changed, 811 insertions, 332 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index 870eafbf20..bbd11efa7e 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -24,7 +24,12 @@ abstract class OverridingPairs extends SymbolPairs {
/** Symbols to exclude: Here these are constructors and private/artifact symbols,
* including bridges. But it may be refined in subclasses.
*/
- override protected def exclude(sym: Symbol) = sym.isPrivateLocal || sym.isArtifact || sym.isConstructor
+ override protected def exclude(sym: Symbol) = (
+ sym.isPrivateLocal
+ || sym.isArtifact
+ || sym.isConstructor
+ || (sym.isPrivate && sym.owner != base) // Privates aren't inherited. Needed for pos/t7475a.scala
+ )
/** Types always match. Term symbols match if their member types
* relative to `self` match.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 088aa5216a..1a53fef4aa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -4891,23 +4891,13 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
asym setInfo logResult(s"Updating bounds of ${asym.fullLocationString} in $tree from '$abounds' to")(TypeBounds(lo, hi))
}
if (asym != null && asym.isAbstractType) {
- // See pos/t1786 to follow what's happening here.
- def canEnhanceIdent = (
- asym.hasCompleteInfo
- && tparam.exists /* sometimes it is NoSymbol */
- && tparam.hasCompleteInfo /* SI-2940 */
- && !tparam.isFBounded /* SI-2251 */
- && !tparam.isHigherOrderTypeParameter
- && !(abounds.hi <:< tbounds.hi)
- && asym.isSynthetic /* this limits us to placeholder tparams, excluding named ones */
- )
arg match {
- case Bind(_, _) => enhanceBounds()
- // TODO: consolidate fixes for SI-6169 and SI-1786 by dropping the Ident case,
- // in favor of doing sharpenQuantifierBounds for all ExistentialTypes, not just java-defined ones
- // (need to figure out how to sharpen the bounds on creation without running into cycles)
- case Ident(name) if canEnhanceIdent => enhanceBounds()
- case _ =>
+ // I removed the Ident() case that partially fixed SI-1786,
+ // because the stricter bounds being inferred broke e.g., slick
+ // worse, the fix was compilation order-dependent
+ // sharpenQuantifierBounds (used in skolemizeExistential) has an alternative fix (SI-6169) that's less invasive
+ case Bind(_, _) => enhanceBounds()
+ case _ =>
}
}
}
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 786b18cd21..26ccd09803 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -23,6 +23,15 @@ import scala.collection.parallel.immutable.ParRange
* println(r2.length) // = 5
* }}}
*
+ * Ranges that contain more than `Int.MaxValue` elements can be created, but
+ * these overfull ranges have only limited capabilities. Any method that
+ * could require a collection of over `Int.MaxValue` length to be created, or
+ * could be asked to index beyond `Int.MaxValue` elements will throw an
+ * exception. Overfull ranges can safely be reduced in size by changing
+ * the step size (e.g. `by 3`) or taking/dropping elements. `contains`,
+ * `equals`, and access to the ends of the range (`head`, `last`, `tail`,
+ * `init`) are also permitted on overfull ranges.
+ *
* @param start the start of this range.
* @param end the exclusive end of the range.
* @param step the step for the range.
@@ -77,10 +86,24 @@ extends scala.collection.AbstractSeq[Int]
}
}
@deprecated("This method will be made private, use `last` instead.", "2.11")
- final val lastElement = start + (numRangeElements - 1) * step
+ final val lastElement =
+ if (isEmpty) start - step
+ else step match {
+ case 1 => if (isInclusive) end else end-1
+ case -1 => if (isInclusive) end else end+1
+ case _ =>
+ val remainder = (gap % step).toInt
+ if (remainder != 0) end - remainder
+ else if (isInclusive) end
+ else end - step
+ }
+
@deprecated("This method will be made private.", "2.11")
- final val terminalElement = start + numRangeElements * step
+ final val terminalElement = lastElement + step
+ /** The last element of this range. This method will return the correct value
+ * even if there are too many elements to iterate over.
+ */
override def last = if (isEmpty) Nil.last else lastElement
override def head = if (isEmpty) Nil.head else start
@@ -149,8 +172,12 @@ extends scala.collection.AbstractSeq[Int]
*/
final override def take(n: Int): Range = (
if (n <= 0 || isEmpty) newEmptyRange(start)
- else if (n >= numRangeElements) this
- else new Range.Inclusive(start, locationAfterN(n - 1), step)
+ else if (n >= numRangeElements && numRangeElements >= 0) this
+ else {
+ // May have more than Int.MaxValue elements in range (numRangeElements < 0)
+ // but the logic is the same either way: take the first n
+ new Range.Inclusive(start, locationAfterN(n - 1), step)
+ }
)
/** Creates a new range containing all the elements of this range except the first `n` elements.
@@ -162,8 +189,12 @@ extends scala.collection.AbstractSeq[Int]
*/
final override def drop(n: Int): Range = (
if (n <= 0 || isEmpty) this
- else if (n >= numRangeElements) newEmptyRange(end)
- else copy(locationAfterN(n), end, step)
+ else if (n >= numRangeElements && numRangeElements >= 0) newEmptyRange(end)
+ else {
+ // May have more than Int.MaxValue elements (numRangeElements < 0)
+ // but the logic is the same either way: go forwards n steps, keep the rest
+ copy(locationAfterN(n), end, step)
+ }
)
/** Creates a new range containing all the elements of this range except the last one.
@@ -192,23 +223,17 @@ extends scala.collection.AbstractSeq[Int]
drop(1)
}
- // Counts how many elements from the start meet the given test.
- private def skipCount(p: Int => Boolean): Int = {
- var current = start
- var counted = 0
-
- while (counted < numRangeElements && p(current)) {
- counted += 1
- current += step
+ // Advance from the start while we meet the given test
+ private def argTakeWhile(p: Int => Boolean): Long = {
+ if (isEmpty) start
+ else {
+ var current = start
+ val stop = last
+ while (current != stop && p(current)) current += step
+ if (current != stop || !p(current)) current
+ else current.toLong + step
}
- counted
}
- // Tests whether a number is within the endpoints, without testing
- // whether it is a member of the sequence (i.e. when step > 1.)
- private def isWithinBoundaries(elem: Int) = !isEmpty && (
- (step > 0 && start <= elem && elem <= last ) ||
- (step < 0 && last <= elem && elem <= start)
- )
// Methods like apply throw exceptions on invalid n, but methods like take/drop
// are forgiving: therefore the checks are with the methods.
private def locationAfterN(n: Int) = start + (step * n)
@@ -219,9 +244,33 @@ extends scala.collection.AbstractSeq[Int]
// based on the given value.
private def newEmptyRange(value: Int) = new Range(value, value, step)
- final override def takeWhile(p: Int => Boolean): Range = take(skipCount(p))
- final override def dropWhile(p: Int => Boolean): Range = drop(skipCount(p))
- final override def span(p: Int => Boolean): (Range, Range) = splitAt(skipCount(p))
+ final override def takeWhile(p: Int => Boolean): Range = {
+ val stop = argTakeWhile(p)
+ if (stop==start) newEmptyRange(start)
+ else {
+ val x = (stop - step).toInt
+ if (x == last) this
+ else new Range.Inclusive(start, x, step)
+ }
+ }
+ final override def dropWhile(p: Int => Boolean): Range = {
+ val stop = argTakeWhile(p)
+ if (stop == start) this
+ else {
+ val x = (stop - step).toInt
+ if (x == last) newEmptyRange(last)
+ else new Range.Inclusive(x + step, last, step)
+ }
+ }
+ final override def span(p: Int => Boolean): (Range, Range) = {
+ val border = argTakeWhile(p)
+ if (border == start) (newEmptyRange(start), this)
+ else {
+ val x = (border - step).toInt
+ if (x == last) (this, newEmptyRange(last))
+ else (new Range.Inclusive(start, x, step), new Range.Inclusive(x+step, last, step))
+ }
+ }
/** Creates a pair of new ranges, first consisting of elements before `n`, and the second
* of elements after `n`.
@@ -234,13 +283,32 @@ extends scala.collection.AbstractSeq[Int]
*
* $doesNotUseBuilders
*/
- final override def takeRight(n: Int): Range = drop(numRangeElements - n)
+ final override def takeRight(n: Int): Range = {
+ if (n <= 0) newEmptyRange(start)
+ else if (numRangeElements >= 0) drop(numRangeElements - n)
+ else {
+ // Need to handle over-full range separately
+ val y = last
+ val x = y - step.toLong*(n-1)
+ if ((step > 0 && x < start) || (step < 0 && x > start)) this
+ else new Range.Inclusive(x.toInt, y, step)
+ }
+ }
/** Creates a new range consisting of the initial `length - n` elements of the range.
*
* $doesNotUseBuilders
*/
- final override def dropRight(n: Int): Range = take(numRangeElements - n)
+ final override def dropRight(n: Int): Range = {
+ if (n <= 0) this
+ else if (numRangeElements >= 0) take(numRangeElements - n)
+ else {
+ // Need to handle over-full range separately
+ val y = last - step.toInt*n
+ if ((step > 0 && y < start) || (step < 0 && y > start)) newEmptyRange(start)
+ else new Range.Inclusive(start, y.toInt, step)
+ }
+ }
/** Returns the reverse of this range.
*
@@ -256,7 +324,17 @@ extends scala.collection.AbstractSeq[Int]
if (isInclusive) this
else new Range.Inclusive(start, end, step)
- final def contains(x: Int) = isWithinBoundaries(x) && ((x - start) % step == 0)
+ final def contains(x: Int) = {
+ if (x==end && !isInclusive) false
+ else if (step > 0) {
+ if (x < start || x > end) false
+ else (step == 1) || (((x - start) % step) == 0)
+ }
+ else {
+ if (x < end || x > start) false
+ else (step == -1) || (((x - start) % step) == 0)
+ }
+ }
final override def sum[B >: Int](implicit num: Numeric[B]): Int = {
if (num eq scala.math.Numeric.IntIsIntegral) {
@@ -285,9 +363,15 @@ extends scala.collection.AbstractSeq[Int]
override def equals(other: Any) = other match {
case x: Range =>
- (x canEqual this) && (length == x.length) && (
- isEmpty || // all empty sequences are equal
- (start == x.start && last == x.last) // same length and same endpoints implies equality
+ // Note: this must succeed for overfull ranges (length > Int.MaxValue)
+ (x canEqual this) && (
+ isEmpty || // all empty sequences are equal
+ (start == x.start && { // Otherwise, must have same start
+ val l0 = last
+ (l0 == x.last && ( // And same end
+ start == l0 || step == x.step // And either the same step, or not take any steps
+ ))
+ })
)
case _ =>
super.equals(other)
@@ -297,7 +381,8 @@ extends scala.collection.AbstractSeq[Int]
*/
override def toString() = {
- val endStr = if (numRangeElements > Range.MAX_PRINT) ", ... )" else ")"
+ val endStr =
+ if (numRangeElements > Range.MAX_PRINT || (!isEmpty && numRangeElements < 0)) ", ... )" else ")"
take(Range.MAX_PRINT).mkString("Range(", ", ", endStr)
}
}
diff --git a/src/library/scala/sys/process/ProcessBuilder.scala b/src/library/scala/sys/process/ProcessBuilder.scala
index 88c0cf8e58..ac86495001 100644
--- a/src/library/scala/sys/process/ProcessBuilder.scala
+++ b/src/library/scala/sys/process/ProcessBuilder.scala
@@ -30,9 +30,7 @@ import ProcessBuilder._
* "ls".!
*
* // Execute "ls" and assign a `Stream[String]` of its output to "contents".
- * // Because [[scala.Predef]] already defines a `lines` method for `String`,
- * // we use [[scala.sys.process.Process]]'s object companion to create it.
- * val contents = Process("ls").lines
+ * val contents = Process("ls").lineStream
*
* // Here we use a `Seq` to make the parameter whitespace-safe
* def contentsOf(dir: String): String = Seq("ls", dir).!!
@@ -82,11 +80,11 @@ import ProcessBuilder._
* of the last one in the chain of execution.
* - `!!`: blocks until all external commands exit, and returns a `String`
* with the output generated.
- * - `lines`: returns immediately like `run`, and the output being generared
+ * - `lineStream`: returns immediately like `run`, and the output being generated
* is provided through a `Stream[String]`. Getting the next element of that
* `Stream` may block until it becomes available. This method will throw an
* exception if the return code is different than zero -- if this is not
- * desired, use the `lines_!` method.
+ * desired, use the `lineStream_!` method.
*
* ==Handling Input and Output==
*
@@ -131,6 +129,14 @@ import ProcessBuilder._
*
* Note: though it is not shown above, the equivalent of a shell's `;` would be
* `###`. The reason for this name is that `;` is a reserved token in Scala.
+ *
+ * Note: the `lines` method, though deprecated, may conflict with the `StringLike`
+ * method of the same name. To avoid this, one may wish to call the builders in
+ * `Process` instead of importing `scala.sys.process._`. The example above would be
+ * {{{
+ * import scala.sys.process.Process
+ * Process("find src -name *.scala -exec grep null {} ;") #| Process("xargs test -z") #&& Process("echo null-free") #|| Process("echo null detected") !
+ * }}}
*/
trait ProcessBuilder extends Source with Sink {
/** Starts the process represented by this builder, blocks until it exits, and
@@ -165,7 +171,11 @@ trait ProcessBuilder extends Source with Sink {
* with a non-zero value, the Stream will provide all lines up to termination
* and then throw an exception.
*/
- def lines: Stream[String]
+ def lineStream: Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream` instead. */
+ @deprecated("Use lineStream instead.", "2.11.0")
+ def lines: Stream[String] = lineStream
/** Starts the process represented by this builder. The output is returned as
* a Stream that blocks when lines are not available but the process has not
@@ -173,7 +183,11 @@ trait ProcessBuilder extends Source with Sink {
* process exits with a non-zero value, the Stream will provide all lines up
* to termination and then throw an exception.
*/
- def lines(log: ProcessLogger): Stream[String]
+ def lineStream(log: ProcessLogger): Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream(log: ProcessLogger)` instead. */
+ @deprecated("Use stream instead.", "2.11.0")
+ def lines(log: ProcessLogger): Stream[String] = lineStream(log)
/** Starts the process represented by this builder. The output is returned as
* a Stream that blocks when lines are not available but the process has not
@@ -181,7 +195,11 @@ trait ProcessBuilder extends Source with Sink {
* with a non-zero value, the Stream will provide all lines up to termination
* but will not throw an exception.
*/
- def lines_! : Stream[String]
+ def lineStream_! : Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream_!` instead. */
+ @deprecated("Use lineStream_! instead.", "2.11.0")
+ def lines_! : Stream[String] = lineStream_!
/** Starts the process represented by this builder. The output is returned as
* a Stream that blocks when lines are not available but the process has not
@@ -189,7 +207,11 @@ trait ProcessBuilder extends Source with Sink {
* process exits with a non-zero value, the Stream will provide all lines up
* to termination but will not throw an exception.
*/
- def lines_!(log: ProcessLogger): Stream[String]
+ def lineStream_!(log: ProcessLogger): Stream[String]
+
+ /** Deprecated (renamed). Use `lineStream_!(log: ProcessLogger)` instead. */
+ @deprecated("Use stream_! instead.", "2.11.0")
+ def lines_!(log: ProcessLogger): Stream[String] = lineStream_!(log)
/** Starts the process represented by this builder, blocks until it exits, and
* returns the exit code. Standard output and error are sent to the console.
diff --git a/src/library/scala/sys/process/ProcessBuilderImpl.scala b/src/library/scala/sys/process/ProcessBuilderImpl.scala
index adf6d1e724..236baaf038 100644
--- a/src/library/scala/sys/process/ProcessBuilderImpl.scala
+++ b/src/library/scala/sys/process/ProcessBuilderImpl.scala
@@ -104,10 +104,10 @@ private[process] trait ProcessBuilderImpl {
def !!< = slurp(None, withIn = true)
def !!<(log: ProcessLogger) = slurp(Some(log), withIn = true)
- def lines: Stream[String] = lines(withInput = false, nonZeroException = true, None)
- def lines(log: ProcessLogger): Stream[String] = lines(withInput = false, nonZeroException = true, Some(log))
- def lines_! : Stream[String] = lines(withInput = false, nonZeroException = false, None)
- def lines_!(log: ProcessLogger): Stream[String] = lines(withInput = false, nonZeroException = false, Some(log))
+ def lineStream: Stream[String] = lineStream(withInput = false, nonZeroException = true, None)
+ def lineStream(log: ProcessLogger): Stream[String] = lineStream(withInput = false, nonZeroException = true, Some(log))
+ def lineStream_! : Stream[String] = lineStream(withInput = false, nonZeroException = false, None)
+ def lineStream_!(log: ProcessLogger): Stream[String] = lineStream(withInput = false, nonZeroException = false, Some(log))
def ! = run(connectInput = false).exitValue()
def !(io: ProcessIO) = run(io).exitValue()
@@ -132,7 +132,7 @@ private[process] trait ProcessBuilderImpl {
else scala.sys.error("Nonzero exit value: " + code)
}
- private[this] def lines(
+ private[this] def lineStream(
withInput: Boolean,
nonZeroException: Boolean,
log: Option[ProcessLogger]
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 17a58d79f6..cf405ade03 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -82,6 +82,7 @@ trait Types
with tpe.GlbLubs
with tpe.TypeMaps
with tpe.TypeConstraints
+ with tpe.FindMembers
with util.Collections { self: SymbolTable =>
import definitions._
@@ -243,18 +244,6 @@ trait Types
}
}
- /** Same as a call to narrow unless existentials are visible
- * after widening the type. In that case, narrow from the widened
- * type instead of the proxy. This gives buried existentials a
- * chance to make peace with the other types. See SI-5330.
- */
- private def narrowForFindMember(tp: Type): Type = {
- val w = tp.widen
- // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type.
- if ((tp ne w) && containsExistential(w)) w.narrow
- else tp.narrow
- }
-
/** The base class for all types */
abstract class Type extends TypeApiImpl with Annotatable[Type] {
/** Types for which asSeenFrom always is the identity, no matter what
@@ -989,64 +978,7 @@ trait Types
*
*/
def findMembers(excludedFlags: Long, requiredFlags: Long): Scope = {
- def findMembersInternal: Scope = {
- var members: Scope = null
- if (Statistics.canEnable) Statistics.incCounter(findMembersCount)
- val start = if (Statistics.canEnable) Statistics.pushTimer(typeOpsStack, findMembersNanos) else null
-
- //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
- var required = requiredFlags
- var excluded = excludedFlags | DEFERRED
- var retryForDeferred = true
- var self: Type = null
- while (retryForDeferred) {
- retryForDeferred = false
- val bcs0 = baseClasses
- var bcs = bcs0
- while (!bcs.isEmpty) {
- val decls = bcs.head.info.decls
- var entry = decls.elems
- while (entry ne null) {
- val sym = entry.sym
- val flags = sym.flags
- if ((flags & required) == required) {
- val excl = flags & excluded
- if (excl == 0L &&
- (// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
- (bcs eq bcs0) ||
- (flags & PrivateLocal) != PrivateLocal ||
- (bcs0.head.hasTransOwner(bcs.head)))) {
- if (members eq null) members = newFindMemberScope
- var others: ScopeEntry = members.lookupEntry(sym.name)
- var symtpe: Type = null
- while ((others ne null) && {
- val other = others.sym
- (other ne sym) &&
- ((other.owner eq sym.owner) ||
- (flags & PRIVATE) != 0 || {
- if (self eq null) self = narrowForFindMember(this)
- if (symtpe eq null) symtpe = self.memberType(sym)
- !(self.memberType(other) matches symtpe)
- })}) {
- others = members lookupNextEntry others
- }
- if (others eq null) members enter sym
- } else if (excl == DEFERRED) {
- retryForDeferred = (excludedFlags & DEFERRED) == 0
- }
- }
- entry = entry.next
- } // while (entry ne null)
- // excluded = excluded | LOCAL
- bcs = bcs.tail
- } // while (!bcs.isEmpty)
- required |= DEFERRED
- excluded &= ~(DEFERRED.toLong)
- } // while (retryForDeferred)
- if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
- if (members eq null) EmptyScope else members
- }
-
+ def findMembersInternal = new FindMembers(this, excludedFlags, requiredFlags).apply()
if (this.isGround) findMembersInternal
else suspendingTypeVars(typeVarsInType(this))(findMembersInternal)
}
@@ -1055,110 +987,13 @@ trait Types
* Find member(s) in this type. If several members matching criteria are found, they are
* returned in an OverloadedSymbol
*
- * @param name The member's name, where nme.ANYNAME means `unspecified`
+ * @param name The member's name
* @param excludedFlags Returned members do not have these flags
* @param requiredFlags Returned members do have these flags
* @param stableOnly If set, return only members that are types or stable values
*/
- //TODO: use narrow only for modules? (correct? efficiency gain?)
def findMember(name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean): Symbol = {
- def findMemberInternal: Symbol = {
- var member: Symbol = NoSymbol
- var members: List[Symbol] = null
- var lastM: ::[Symbol] = null
- if (Statistics.canEnable) Statistics.incCounter(findMemberCount)
- val start = if (Statistics.canEnable) Statistics.pushTimer(typeOpsStack, findMemberNanos) else null
-
- //Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
- var membertpe: Type = null
- var required = requiredFlags
- var excluded = excludedFlags | DEFERRED
- var continue = true
- var self: Type = null
-
- while (continue) {
- continue = false
- val bcs0 = baseClasses
- var bcs = bcs0
- // omit PRIVATE LOCALS unless selector class is contained in class owning the def.
- def admitPrivateLocal(owner: Symbol): Boolean = {
- val selectorClass = this match {
- case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class.
- case _ => bcs0.head
- }
- selectorClass.hasTransOwner(owner)
- }
- while (!bcs.isEmpty) {
- val decls = bcs.head.info.decls
- var entry = decls.lookupEntry(name)
- while (entry ne null) {
- val sym = entry.sym
- val flags = sym.flags
- if ((flags & required) == required) {
- val excl = flags & excluded
- if (excl == 0L &&
- (
- (bcs eq bcs0) ||
- (flags & PrivateLocal) != PrivateLocal ||
- admitPrivateLocal(bcs.head))) {
- if (name.isTypeName || (stableOnly && sym.isStable && !sym.hasVolatileType)) {
- if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
- return sym
- } else if (member eq NoSymbol) {
- member = sym
- } else if (members eq null) {
- if ((member ne sym) &&
- ((member.owner eq sym.owner) ||
- (flags & PRIVATE) != 0 || {
- if (self eq null) self = narrowForFindMember(this)
- if (membertpe eq null) membertpe = self.memberType(member)
- !(membertpe matches self.memberType(sym))
- })) {
- lastM = new ::(sym, null)
- members = member :: lastM
- }
- } else {
- var others: List[Symbol] = members
- var symtpe: Type = null
- while ((others ne null) && {
- val other = others.head
- (other ne sym) &&
- ((other.owner eq sym.owner) ||
- (flags & PRIVATE) != 0 || {
- if (self eq null) self = narrowForFindMember(this)
- if (symtpe eq null) symtpe = self.memberType(sym)
- !(self.memberType(other) matches symtpe)
- })}) {
- others = others.tail
- }
- if (others eq null) {
- val lastM1 = new ::(sym, null)
- lastM.tl = lastM1
- lastM = lastM1
- }
- }
- } else if (excl == DEFERRED) {
- continue = true
- }
- }
- entry = decls lookupNextEntry entry
- } // while (entry ne null)
- // excluded = excluded | LOCAL
- bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail
- } // while (!bcs.isEmpty)
- required |= DEFERRED
- excluded &= ~(DEFERRED.toLong)
- } // while (continue)
- if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
- if (members eq null) {
- if (member == NoSymbol) if (Statistics.canEnable) Statistics.incCounter(noMemberCount)
- member
- } else {
- if (Statistics.canEnable) Statistics.incCounter(multMemberCount)
- lastM.tl = Nil
- baseClasses.head.newOverloaded(this, members)
- }
- }
+ def findMemberInternal = new FindMember(this, name, excludedFlags, requiredFlags, stableOnly).apply()
if (this.isGround) findMemberInternal
else suspendingTypeVars(typeVarsInType(this))(findMemberInternal)
diff --git a/src/reflect/scala/reflect/internal/tpe/FindMembers.scala b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala
new file mode 100644
index 0000000000..de54f3768e
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/tpe/FindMembers.scala
@@ -0,0 +1,288 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2014 LAMP/EPFL
+ * @author Jason Zaugg
+ */
+package scala.reflect.internal
+package tpe
+
+import Flags._
+import util.Statistics
+import TypesStats._
+
+trait FindMembers {
+ this: SymbolTable =>
+
+ /** Implementatation of `Type#{findMember, findMembers}` */
+ private[internal] abstract class FindMemberBase[T](tpe: Type, name: Name, excludedFlags: Long, requiredFlags: Long) {
+ protected val initBaseClasses: List[Symbol] = tpe.baseClasses
+
+ // The first base class, or the symbol of the ThisType
+ // e.g in:
+ // trait T { self: C => }
+ //
+ // The selector class of `T.this.type` is `T`, and *not* the first base class, `C`.
+ private[this] var _selectorClass: Symbol = null
+ private def selectorClass: Symbol = {
+ if (_selectorClass eq null) {
+ _selectorClass = tpe match {
+ case tt: ThisType => tt.sym // SI-7507 the first base class is not necessarily the selector class.
+ case _ => initBaseClasses.head
+ }
+ }
+ _selectorClass
+ }
+
+ // Cache for the narrowed type of `tp` (in `tp.findMember`).
+ // This is needed to avoid mismatched existential types are reported in SI-5330.
+ private[this] var _self: Type = null
+ protected def self: Type = {
+ // TODO: use narrow only for modules? (correct? efficiency gain?) (<-- Note: this comment predates SI-5330)
+ if (_self eq null) _self = narrowForFindMember(tpe)
+ _self
+ }
+
+ // Main entry point
+ def apply(): T = {
+ if (Statistics.canEnable) Statistics.incCounter(findMemberCount)
+ val start = if (Statistics.canEnable) Statistics.pushTimer(typeOpsStack, findMemberNanos) else null
+ try searchConcreteThenDeferred
+ finally if (Statistics.canEnable) Statistics.popTimer(typeOpsStack, start)
+ }
+
+ protected def result: T
+
+ // SLS 5.1.3 First, a concrete definition always overrides an abstract definition
+ private def searchConcreteThenDeferred: T = {
+ val deferredSeen = walkBaseClasses(requiredFlags, excludedFlags | DEFERRED)
+ if (deferredSeen) // OPT: the `if` avoids a second pass if the first pass didn't spot any candidates.
+ walkBaseClasses(requiredFlags | DEFERRED, excludedFlags & ~(DEFERRED.toLong))
+ result
+ }
+
+ /*
+ * Walk up through the decls of each base class.
+ *
+ * Called in two passes: first excluding deferred, then mandating it.
+ *
+ * @return if a potential deferred member was seen on the first pass that calls for a second pass,
+ and `excluded & DEFERRED != 0L`
+ */
+ private def walkBaseClasses(required: Long, excluded: Long): Boolean = {
+ var bcs = initBaseClasses
+
+ // Have we seen a candidate deferred member?
+ var deferredSeen = false
+
+ // All direct parents of refinement classes in the base class sequence
+ // from the current `walkBaseClasses`
+ var refinementParents: List[Symbol] = Nil
+
+ // Has the current `walkBaseClasses` encountered a non-refinement class?
+ var seenFirstNonRefinementClass = false
+
+ val findAll = name == nme.ANYname
+
+ while (!bcs.isEmpty) {
+ val currentBaseClass = bcs.head
+ val decls = currentBaseClass.info.decls
+ var entry = if (findAll) decls.elems else decls.lookupEntry(name)
+ while (entry ne null) {
+ val sym = entry.sym
+ val flags = sym.flags
+ val meetsRequirements = (flags & required) == required
+ if (meetsRequirements) {
+ val excl: Long = flags & excluded
+ val isExcluded: Boolean = excl != 0L
+ if (!isExcluded && isPotentialMember(sym, flags, currentBaseClass, seenFirstNonRefinementClass, refinementParents)) {
+ if (shortCircuit(sym)) return false
+ else addMemberIfNew(sym)
+ } else if (excl == DEFERRED) {
+ deferredSeen = true
+ }
+ }
+ entry = if (findAll) entry.next else decls lookupNextEntry entry
+ }
+
+ // SLS 5.2 The private modifier can be used with any definition or declaration in a template.
+ // They are not inherited by subclasses [...]
+ if (currentBaseClass.isRefinementClass)
+ // SLS 3.2.7 A compound type T1 with . . . with Tn {R } represents objects with members as given in
+ // the component types T1, ..., Tn and the refinement {R }
+ //
+ // => private members should be included from T1, ... Tn. (SI-7475)
+ refinementParents :::= currentBaseClass.parentSymbols
+ else if (currentBaseClass.isClass)
+ seenFirstNonRefinementClass = true // only inherit privates of refinement parents after this point
+
+ bcs = bcs.tail
+ }
+ deferredSeen
+ }
+
+ /* Should this symbol be returned immediately as the sole result? */
+ protected def shortCircuit(sym: Symbol): Boolean
+
+ /* Add this member to the final result, unless an already-found member matches it. */
+ protected def addMemberIfNew(sym: Symbol): Unit
+
+ // Is `sym` a potentially member of `baseClass`?
+ //
+ // Q. When does a potential member fail to be a an actual member?
+ // A. if it is subsumed by an member in a subclass.
+ private def isPotentialMember(sym: Symbol, flags: Long, owner: Symbol,
+ seenFirstNonRefinementClass: Boolean, refinementParents: List[Symbol]): Boolean = {
+ // conservatively (performance wise) doing this with flags masks rather than `sym.isPrivate`
+ // to avoid multiple calls to `Symbol#flags`.
+ val isPrivate = (flags & PRIVATE) == PRIVATE
+ val isPrivateLocal = (flags & PrivateLocal) == PrivateLocal
+
+ // TODO Is the special handling of `private[this]` vs `private` backed up by the spec?
+ def admitPrivate(sym: Symbol): Boolean =
+ (selectorClass == owner) || (
+ !isPrivateLocal // private[this] only a member from within the selector class. (Optimization only? Does the spec back this up?)
+ && (
+ !seenFirstNonRefinementClass
+ || refinementParents.contains(owner)
+ )
+ )
+
+ (!isPrivate || admitPrivate(sym)) && (sym.name != nme.CONSTRUCTOR || owner == initBaseClasses.head)
+ }
+
+ // True unless the already-found member of type `memberType` matches the candidate symbol `other`.
+ protected def isNewMember(member: Symbol, other: Symbol): Boolean =
+ ( (other ne member)
+ && ( (member.owner eq other.owner) // same owner, therefore overload
+ || (member.flags & PRIVATE) != 0 // (unqualified) private members never participate in overriding
+ || (other.flags & PRIVATE) != 0 // ... as overrider or overridee.
+ || !(memberTypeLow(member) matches memberTypeHi(other)) // do the member types match? If so, its an override. Otherwise it's an overload.
+ )
+ )
+
+ // Cache for the member type of a candidate member when comparing against multiple, already-found existing members
+ //
+ // TODO this cache is probably unnecessary, `tp.memberType(sym: MethodSymbol)` is already cached internally.
+ private[this] var _memberTypeHiCache: Type = null
+ private[this] var _memberTypeHiCacheSym: Symbol = null
+
+ protected def memberTypeHi(sym: Symbol): Type = {
+ if (_memberTypeHiCacheSym ne sym) {
+ _memberTypeHiCache = self.memberType(sym)
+ _memberTypeHiCacheSym = sym
+ }
+ _memberTypeHiCache
+ }
+
+ // member type of the LHS of `matches` call. This is an extension point to enable a cache in
+ // FindMember.
+ protected def memberTypeLow(sym: Symbol): Type = self.memberType(sym)
+
+ /** Same as a call to narrow unless existentials are visible
+ * after widening the type. In that case, narrow from the widened
+ * type instead of the proxy. This gives buried existentials a
+ * chance to make peace with the other types. See SI-5330.
+ */
+ private def narrowForFindMember(tp: Type): Type = {
+ val w = tp.widen
+ // Only narrow on widened type when we have to -- narrow is expensive unless the target is a singleton type.
+ if ((tp ne w) && containsExistential(w)) w.narrow
+ else tp.narrow
+ }
+ }
+
+ private[reflect] final class FindMembers(tpe: Type, excludedFlags: Long, requiredFlags: Long)
+ extends FindMemberBase[Scope](tpe, nme.ANYname, excludedFlags, requiredFlags) {
+ private[this] var _membersScope: Scope = null
+ private def membersScope: Scope = {
+ if (_membersScope eq null) _membersScope = newFindMemberScope
+ _membersScope
+ }
+
+ protected def shortCircuit(sym: Symbol): Boolean = false
+ protected def result: Scope = membersScope
+
+ protected def addMemberIfNew(sym: Symbol): Unit = {
+ val members = membersScope
+ var others = members.lookupEntry(sym.name)
+ var isNew = true
+ while ((others ne null) && isNew) {
+ val member = others.sym
+ if (!isNewMember(member, sym))
+ isNew = false
+ others = members lookupNextEntry others // next existing member with the same name.
+ }
+ if (isNew) members.enter(sym)
+ }
+ }
+
+ private[reflect] final class FindMember(tpe: Type, name: Name, excludedFlags: Long, requiredFlags: Long, stableOnly: Boolean)
+ extends FindMemberBase[Symbol](tpe, name, excludedFlags, requiredFlags) {
+ // Gathering the results into a hand rolled ListBuffer
+ // TODO Try just using a ListBuffer to see if this low-level-ness is worth it.
+ private[this] var member0: Symbol = NoSymbol
+ private[this] var members: List[Symbol] = null
+ private[this] var lastM: ::[Symbol] = null
+
+ private def clearAndAddResult(sym: Symbol): Unit = {
+ member0 = sym
+ members = null
+ lastM = null
+ }
+
+ protected def shortCircuit(sym: Symbol): Boolean = (name.isTypeName || (stableOnly && sym.isStable && !sym.hasVolatileType)) && {
+ clearAndAddResult(sym)
+ true
+ }
+
+ protected def addMemberIfNew(sym: Symbol): Unit =
+ if (member0 eq NoSymbol) {
+ member0 = sym // The first found member
+ } else if (members eq null) {
+ // We've found exactly one member so far...
+ if (isNewMember(member0, sym)) {
+ // ... make that two.
+ lastM = new ::(sym, null)
+ members = member0 :: lastM
+ }
+ } else {
+ // Already found 2 or more members
+ var ms: List[Symbol] = members
+
+ var isNew = true
+ while ((ms ne null) && isNew) {
+ val member = ms.head
+ if (!isNewMember(member, sym))
+ isNew = false
+ ms = ms.tail
+ }
+ if (isNew) {
+ val lastM1 = new ::(sym, null)
+ lastM.tl = lastM1
+ lastM = lastM1
+ }
+ }
+
+ // Cache for the member type of the first member we find.
+ private[this] var _member0Tpe: Type = null
+ private[this] def member0Tpe: Type = {
+ assert(member0 != null)
+ if (_member0Tpe eq null) _member0Tpe = self.memberType(member0)
+ _member0Tpe
+ }
+
+ override protected def memberTypeLow(sym: Symbol): Type =
+ if (sym eq member0) member0Tpe else super.memberTypeLow(sym)
+
+ // Assemble the result from the hand-rolled ListBuffer
+ protected def result: Symbol = if (members eq null) {
+ if (member0 == NoSymbol) {
+ if (Statistics.canEnable) Statistics.incCounter(noMemberCount)
+ NoSymbol
+ } else member0
+ } else {
+ if (Statistics.canEnable) Statistics.incCounter(multMemberCount)
+ lastM.tl = Nil
+ initBaseClasses.head.newOverloaded(tpe, members)
+ }
+ }
+}
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index fb893cbff1..0fcf215580 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -27,27 +27,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.settings
this.treeInfo
- // inaccessible: this.scala$reflect$runtime$Gil$$gil
- // inaccessible: this.uniqueLock
- // inaccessible: this._skolemizationLevel
- // inaccessible: this._undoLog
- // inaccessible: this._intersectionWitness
- // inaccessible: this._subsametypeRecursions
- // inaccessible: this._pendingSubTypes
- // inaccessible: this._basetypeRecursions
- // inaccessible: this._pendingBaseTypes
- // inaccessible: this._lubResults
- // inaccessible: this._glbResults
- // inaccessible: this._indent
- // inaccessible: this._toStringRecursions
- // inaccessible: this._toStringSubjects
- // inaccessible: this.atomicIds
- // inaccessible: this.atomicExistentialIds
- // inaccessible: this._recursionTable
- // inaccessible: this.mirrors
this.rootMirror
this.treeBuild
- // inaccessible: this.SimpleNameOrdering
this.traceSymbols
this.perRunCaches
this.FreshNameExtractor
@@ -60,7 +41,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.SubpatternsAttachment
this.noPrint
this.typeDebug
- // inaccessible: this.maxFree
this.Range
// inaccessible: this.posAssigner
this.ConsoleWriter
@@ -116,7 +96,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.pendingSuperCall
this.emptyValDef
this.EmptyTreeTypeSubstituter
- // inaccessible: this.duplicator
this.UnmappableAnnotArg
this.LiteralAnnotArg
this.ArrayAnnotArg
@@ -127,7 +106,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.UnmappableAnnotation
this.ErroneousAnnotation
this.ThrownException
- // inaccessible: this.compactify
this.tpnme
this.fulltpnme
this.binarynme
@@ -147,7 +125,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.ProperTypeKind
this.TypeConKind
this.inferKind
- // inaccessible: this.substTypeMapCache
this.UnmappableTree
this.ErrorType
this.WildcardType
@@ -184,9 +161,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.unwrapToStableClass
this.unwrapWrapperTypes
this.RecoverableCyclicReference
- // inaccessible: this._undoLog
- // inaccessible: this.numericLoBound
- // inaccessible: this.numericHiBound
this.TypeConstraint
this.normalizeAliases
this.dropSingletonType
@@ -198,19 +172,16 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.typeVarToOriginMap
this.ErroneousCollector
this.adaptToNewRunMap
- // inaccessible: this.commonOwnerMapObj
this.SubTypePair
this.SymbolKind
this.NoSymbol
this.CyclicReference
- // inaccessible: this.TypeHistory
this.SymbolOps
this.TermName
this.TypeName
this.Liftable
this.Unliftable
this.BooleanFlag
- // inaccessible: this.CachedNames
this.WeakTypeTag
this.TypeTag
this.Expr
@@ -427,14 +398,12 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.languageFeatureModule
definitions.metaAnnotations
definitions.AnnotationDefaultAttr
- // inaccessible: definitions.erasurePhase
definitions.isPhantomClass
definitions.syntheticCoreClasses
definitions.syntheticCoreMethods
definitions.hijackedCoreClasses
definitions.symbolsNotPresentInBytecode
definitions.isPossibleSyntheticParent
- // inaccessible: definitions.boxedValueClassesSet
definitions.abbrvTag
definitions.numericWeight
definitions.boxedModule
diff --git a/test/files/neg/forgot-interpolator.check b/test/files/neg/forgot-interpolator.check
index 157cbb4802..8988458982 100644
--- a/test/files/neg/forgot-interpolator.check
+++ b/test/files/neg/forgot-interpolator.check
@@ -10,9 +10,6 @@ forgot-interpolator.scala:30: warning: `$beppo` looks like an interpolated ident
forgot-interpolator.scala:34: warning: `$aleppo` looks like an interpolated identifier! Did you forget the interpolator?
def f = "$aleppo is a pepper and a city." // warn 4
^
-forgot-interpolator.scala:42: warning: `$bar` looks like an interpolated identifier! Did you forget the interpolator?
- def f = "$bar is private, shall we warn just in case?" // warn 5
- ^
forgot-interpolator.scala:47: warning: `$hippo` looks like an interpolated identifier! Did you forget the interpolator?
def h = "$hippo takes an implicit" // warn 6
^
@@ -26,5 +23,5 @@ forgot-interpolator.scala:90: warning: `$calico` looks like an interpolated iden
def f4 = "I also salute $calico" // warn 9
^
error: No warnings can be incurred under -Xfatal-warnings.
-9 warnings found
+8 warnings found
one error found
diff --git a/test/files/neg/forgot-interpolator.scala b/test/files/neg/forgot-interpolator.scala
index 34a7c7aef4..a53054d890 100644
--- a/test/files/neg/forgot-interpolator.scala
+++ b/test/files/neg/forgot-interpolator.scala
@@ -39,7 +39,7 @@ package test {
if (bar > 8) ??? // use it to avoid extra warning
}
class Baz extends Bar {
- def f = "$bar is private, shall we warn just in case?" // warn 5
+ def f = "$bar is private, shall we warn just in case?" // no longer a warning, private members aren't inherited!
}
class G {
def g = "$greppo takes an arg" // no warn
diff --git a/test/files/neg/t0764b.check b/test/files/neg/t0764b.check
new file mode 100644
index 0000000000..d74a9efbfe
--- /dev/null
+++ b/test/files/neg/t0764b.check
@@ -0,0 +1,63 @@
+t0764b.scala:27: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.NodeAlias[p1.t0764.NodeAlias[A]]
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f1 = new Main1(v.prepend) // fail
+ ^
+t0764b.scala:28: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.NodeAlias[p1.t0764.NodeAlias[A]]
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:29: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.NodeAlias[p1.t0764.Node{type T = A}]
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ ^
+t0764b.scala:34: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f1 = new Main2(v.prepend) // fail
+ ^
+t0764b.scala:35: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.Node{type T = p1.t0764.NodeAlias[A]}
+ (which expands to) p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:36: error: type mismatch;
+ found : p1.t0764.Node{type T = p1.t0764.<refinement>.type}
+ required: p1.t0764.Node{type T = p1.t0764.Node{type T = A}}
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ ^
+t0764b.scala:52: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.NodeAlias[p2.t0764.NodeAlias[A]]
+ (which expands to) p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:53: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.NodeAlias[p2.t0764.Node{type T = A}]
+ (which expands to) p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ ^
+t0764b.scala:58: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f1 = new Main2(v.prepend) // fail
+ ^
+t0764b.scala:59: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.Node{type T = p2.t0764.NodeAlias[A]}
+ (which expands to) p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ ^
+t0764b.scala:60: error: type mismatch;
+ found : p2.t0764.Node{type T = p2.t0764.<refinement>.type}
+ required: p2.t0764.Node{type T = p2.t0764.Node{type T = A}}
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ ^
+11 errors found
diff --git a/test/files/neg/t0764b.scala b/test/files/neg/t0764b.scala
new file mode 100644
index 0000000000..4ad5ecdc03
--- /dev/null
+++ b/test/files/neg/t0764b.scala
@@ -0,0 +1,64 @@
+/** Note that this should compile! It's a neg test to track the
+behavior. If you have broken this test by making it compile, that
+means you have fixed it and it should be moved to pos.
+**/
+
+// In all cases when calling "prepend" the receiver 'v'
+// has static type NodeAlias[A] or (equivalently) Node { type T = A }.
+// Since prepend explicitly returns the singleton type of the receiver,
+// the return type of prepend in all cases is "v.type", and so the call
+// to "new Main" can be parameterized with any of the following, in order
+// of decreasing specificity with a tie for second place:
+//
+// new Main[v.type](v.prepend)
+// new Main[NodeAlias[A]](v.prepend)
+// new Main[Node { type T = A }](v.prepend)
+// new Main(v.prepend)
+
+package p1 {
+ object t0764 {
+ type NodeAlias[A] = Node { type T = A }
+ trait Node { outer =>
+ type T <: Node
+ def prepend: Node { type T = outer.type } = ???
+ }
+
+ class Main1[A <: Node](v: NodeAlias[A]) {
+ private[this] def f1 = new Main1(v.prepend) // fail
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main1[v.type](v.prepend) // ok
+ }
+
+ class Main2[A <: Node](v: Node { type T = A }) {
+ private[this] def f1 = new Main2(v.prepend) // fail
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main2[v.type](v.prepend) // ok
+ }
+ }
+}
+
+package p2 {
+ object t0764 {
+ type NodeAlias[A] = Node { type T = A }
+ trait Node { outer =>
+ type T <: Node
+ def prepend: NodeAlias[outer.type] = ???
+ }
+
+ class Main1[A <: Node](v: NodeAlias[A]) {
+ private[this] def f1 = new Main1(v.prepend) // ok! <<========== WOT
+ private[this] def f2 = new Main1[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main1[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main1[v.type](v.prepend) // ok
+ }
+
+ class Main2[A <: Node](v: Node { type T = A }) {
+ private[this] def f1 = new Main2(v.prepend) // fail
+ private[this] def f2 = new Main2[NodeAlias[A]](v.prepend) // fail
+ private[this] def f3 = new Main2[Node { type T = A }](v.prepend) // fail
+ private[this] def f4 = new Main2[v.type](v.prepend) // ok
+ }
+ }
+}
diff --git a/test/files/neg/t7475c.check b/test/files/neg/t7475c.check
new file mode 100644
index 0000000000..472808131a
--- /dev/null
+++ b/test/files/neg/t7475c.check
@@ -0,0 +1,7 @@
+t7475c.scala:6: error: value a is not a member of A.this.B
+ println(this.a) // wait, what?
+ ^
+t7475c.scala:7: error: value b is not a member of A.this.B
+ println(this.b) // wait, what?
+ ^
+two errors found
diff --git a/test/files/neg/t7475c.scala b/test/files/neg/t7475c.scala
new file mode 100644
index 0000000000..cd4a8762ca
--- /dev/null
+++ b/test/files/neg/t7475c.scala
@@ -0,0 +1,9 @@
+class A {
+ private val a: Int = 0
+ private[this] val b: Int = 0
+ class B extends A {
+ def foo(a: A) = a.a // okay
+ println(this.a) // wait, what?
+ println(this.b) // wait, what?
+ }
+}
diff --git a/test/files/neg/t7475d.check b/test/files/neg/t7475d.check
new file mode 100644
index 0000000000..6bd1da0d44
--- /dev/null
+++ b/test/files/neg/t7475d.check
@@ -0,0 +1,7 @@
+t7475d.scala:4: error: value priv is not a member of T.this.TT
+ (??? : TT).priv
+ ^
+t7475d.scala:10: error: value priv is not a member of U.this.UU
+ (??? : UU).priv
+ ^
+two errors found
diff --git a/test/files/neg/t7475e.check b/test/files/neg/t7475e.check
new file mode 100644
index 0000000000..48af2be51a
--- /dev/null
+++ b/test/files/neg/t7475e.check
@@ -0,0 +1,4 @@
+t7475e.scala:8: error: value priv is not a member of Base.this.TT
+ (??? : TT).priv
+ ^
+one error found
diff --git a/test/files/neg/t7475e.scala b/test/files/neg/t7475e.scala
new file mode 100644
index 0000000000..e5c4877d6e
--- /dev/null
+++ b/test/files/neg/t7475e.scala
@@ -0,0 +1,12 @@
+trait U {
+}
+
+trait Base {
+ private val priv = 0
+
+ type TT = U with T // should exclude `priv`
+ (??? : TT).priv
+}
+
+trait T extends Base {
+}
diff --git a/test/files/neg/t7475f.check b/test/files/neg/t7475f.check
new file mode 100644
index 0000000000..a07a4480e2
--- /dev/null
+++ b/test/files/neg/t7475f.check
@@ -0,0 +1,10 @@
+t7475f.scala:12: error: method c1 in class C cannot be accessed in C[T]
+ c1 // a member, but inaccessible.
+ ^
+t7475f.scala:13: error: not found: value c2
+ c2 // a member, but inaccessible.
+ ^
+t7475f.scala:26: error: value d2 is not a member of D[Any]
+ other.d2 // not a member
+ ^
+three errors found
diff --git a/test/files/neg/t7475f.scala b/test/files/neg/t7475f.scala
new file mode 100644
index 0000000000..6c5feadf19
--- /dev/null
+++ b/test/files/neg/t7475f.scala
@@ -0,0 +1,28 @@
+class C[T] extends D[T] {
+ private def c1 = 0
+ private[this] def c2 = 0
+}
+
+trait D[T] {
+ self: C[T] =>
+
+ private def d1 = 0
+ private[this] def d2 = 0
+
+ c1 // a member, but inaccessible.
+ c2 // a member, but inaccessible.
+
+ d1 // okay
+ d2 // okay
+
+
+ class C {
+ d1
+ d2
+ }
+
+ def x(other: D[Any]) {
+ other.d1
+ other.d2 // not a member
+ }
+}
diff --git a/test/files/neg/t7507.check b/test/files/neg/t7507.check
index d402869fd4..de30fc7057 100644
--- a/test/files/neg/t7507.check
+++ b/test/files/neg/t7507.check
@@ -1,4 +1,4 @@
-t7507.scala:6: error: value bippy in trait Cake cannot be accessed in Cake
+t7507.scala:6: error: not found: value bippy
locally(bippy)
^
one error found
diff --git a/test/files/pos/t1786-counter.scala b/test/files/pos/t1786-counter.scala
new file mode 100644
index 0000000000..c1ad2c204f
--- /dev/null
+++ b/test/files/pos/t1786-counter.scala
@@ -0,0 +1,38 @@
+trait ShapeLevel
+
+object Fail {
+ abstract class ProductNodeShape[Level <: ShapeLevel, C, M <: C, U <: C, P <: C] extends Shape[Level, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _]
+ }
+
+ abstract class Shape[Level <: ShapeLevel, -Mixed_, Unpacked_, Packed_]
+
+ final class TupleShape[Level <: ShapeLevel, M <: Product, U <: Product, P <: Product](val shapes: Shape[_, _, _, _]*) extends ProductNodeShape[Level, Product, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _] = ???
+ }
+
+ trait ShapeLevel
+}
+
+object Ok {
+ abstract class Shape[Level <: ShapeLevel, -Mixed_, Unpacked_, Packed_]
+
+ abstract class ProductNodeShape[Level <: ShapeLevel, C, M <: C, U <: C, P <: C] extends Shape[Level, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _]
+ }
+
+ final class TupleShape[Level <: ShapeLevel, M <: Product, U <: Product, P <: Product](val shapes: Shape[_, _, _, _]*) extends ProductNodeShape[Level, Product, M, U, P] {
+ def copy(shapes: Seq[Shape[_, _, _, _]]): Shape[Level, _, _, _] = ???
+ }
+}
+
+// This is why we reverted the fix for SI-1786 -- see SI-6169 for a potential alternative that could be extended to cover this.
+// both objects type check on 2.10.3, but only Ok was accepted by 2.11 after the original fix to SI-1786.
+// Fail results in:
+/*
+t1786-counter.scala:10: error: class TupleShape needs to be abstract, since method copy in class ProductNodeShape of type (shapes: Seq[Fail.Shape[_, _, _, _]])Fail.Shape[Level, _, _, _] is not defined
+(Note that Seq[Fail.Shape[_, _, _, _]] does not match Seq[Fail.Shape[_ <: Fail.ShapeLevel, _, _, _]]: their type parameters differ)
+ final class TupleShape[Level <: ShapeLevel, M <: Product, U <: Product, P <: Product](val shapes: Shape[_, _, _, _]*) extends ProductNodeShape[Level, Product, M, U, P] {
+ ^
+one error found
+*/ \ No newline at end of file
diff --git a/test/files/pos/t261-ab.scala b/test/files/pos/t261-ab.scala
deleted file mode 100644
index df641e811a..0000000000
--- a/test/files/pos/t261-ab.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-trait A { val foo: String = "A" }
-trait B {
- private val foo: String = "B"
- def f = println(foo)
-}
-object Test extends App with B with A {
- println(foo) // prints "A", as expected
- f // prints "B", as expected
-}
diff --git a/test/files/pos/t261-ba.scala b/test/files/pos/t261-ba.scala
deleted file mode 100644
index 6c9c5b10b7..0000000000
--- a/test/files/pos/t261-ba.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-trait B {
- private val foo: String = "B"
- def f = println(foo)
-}
-trait A { val foo: String = "A" }
-object Test extends App with B with A {
- println(foo) // prints "A", as expected
- f // prints "B", as expected
-}
diff --git a/test/files/pos/t7475a.scala b/test/files/pos/t7475a.scala
new file mode 100644
index 0000000000..810ce9a05c
--- /dev/null
+++ b/test/files/pos/t7475a.scala
@@ -0,0 +1,11 @@
+trait AbstractPublic {
+ def queue: Any
+}
+trait ConcretePrivate {
+ private val queue: Any = ()
+}
+
+abstract class Mix
+ extends ConcretePrivate with AbstractPublic {
+ final def queue: Any = ()
+}
diff --git a/test/files/pos/t7475b.scala b/test/files/pos/t7475b.scala
new file mode 100644
index 0000000000..a34743b8be
--- /dev/null
+++ b/test/files/pos/t7475b.scala
@@ -0,0 +1,8 @@
+trait U {
+}
+
+trait T {
+ type TT = Any with T with U
+ private val priv = 0
+ (??? : TT).priv
+}
diff --git a/test/files/pos/t7475d.scala b/test/files/pos/t7475d.scala
new file mode 100644
index 0000000000..497c2bf443
--- /dev/null
+++ b/test/files/pos/t7475d.scala
@@ -0,0 +1,11 @@
+trait T {
+ type TT = T with Any
+ private val priv = 0
+ (??? : TT).priv
+}
+
+trait U {
+ type UU = Any with U
+ private val priv = 0
+ (??? : UU).priv
+}
diff --git a/test/files/pos/t7475e.scala b/test/files/pos/t7475e.scala
new file mode 100644
index 0000000000..fbc965c4ca
--- /dev/null
+++ b/test/files/pos/t7475e.scala
@@ -0,0 +1,13 @@
+trait U {
+ private val priv = 0
+ type TT = U with T // should allow `priv`
+ (??? : TT).priv
+}
+
+trait Base {
+
+}
+
+trait T extends Base {
+
+}
diff --git a/test/files/presentation/ide-bug-1000531.check b/test/files/presentation/ide-bug-1000531.check
index ef8a1d12de..d8c7a369f7 100644
--- a/test/files/presentation/ide-bug-1000531.check
+++ b/test/files/presentation/ide-bug-1000531.check
@@ -3,7 +3,7 @@ reload: CrashOnLoad.scala
askTypeCompletion at CrashOnLoad.scala(6,12)
================================================================================
[response] askTypeCompletion at (6,12)
-retrieved 118 members
+retrieved 117 members
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
[inaccessible] protected[this] def reversed: List[B]
diff --git a/test/files/presentation/ping-pong.check b/test/files/presentation/ping-pong.check
index ab4cfc9e7a..220bdf33b2 100644
--- a/test/files/presentation/ping-pong.check
+++ b/test/files/presentation/ping-pong.check
@@ -3,7 +3,7 @@ reload: PingPong.scala
askTypeCompletion at PingPong.scala(10,23)
================================================================================
[response] askTypeCompletion at (10,23)
-retrieved 33 members
+retrieved 32 members
[inaccessible] private[this] val ping: Ping
[inaccessible] protected[package lang] def clone(): Object
[inaccessible] protected[package lang] def finalize(): Unit
diff --git a/test/files/presentation/scope-completion-3.check b/test/files/presentation/scope-completion-3.check
index df3007ab4e..b70a7d5c6b 100644
--- a/test/files/presentation/scope-completion-3.check
+++ b/test/files/presentation/scope-completion-3.check
@@ -3,19 +3,7 @@ reload: Completions.scala
askScopeCompletion at Completions.scala(75,2)
================================================================================
[response] askScopeCompletion at (75,2)
-retrieved 49 members
-[inaccessible] private class Cb2 extends AnyRef
-[inaccessible] private class Ct2 extends AnyRef
-[inaccessible] private def fb2: Int
-[inaccessible] private def ft2: Int
-[inaccessible] private object Ob2
-[inaccessible] private object Ot2
-[inaccessible] private type tb2 = Completion1.this.tb2
-[inaccessible] private type tt2 = Completion1.this.tt2
-[inaccessible] private[this] val vb2: Int
-[inaccessible] private[this] val vt2: Int
-[inaccessible] private[this] var rb2: Int
-[inaccessible] private[this] var rt2: Int
+retrieved 37 members
abstract class Base1 extends AnyRef
abstract trait Trait1 extends AnyRef
class Cb1 extends AnyRef
@@ -58,19 +46,7 @@ type tt1 = Completion1.this.tt1
askScopeCompletion at Completions.scala(104,2)
================================================================================
[response] askScopeCompletion at (104,2)
-retrieved 49 members
-[inaccessible] private class Cb2 extends AnyRef
-[inaccessible] private class Ct2 extends AnyRef
-[inaccessible] private def fb2: Int
-[inaccessible] private def ft2: Int
-[inaccessible] private object Ob2
-[inaccessible] private object Ot2
-[inaccessible] private type tb2 = test.Completion2.tb2
-[inaccessible] private type tt2 = test.Completion2.tt2
-[inaccessible] private[this] val vb2: Int
-[inaccessible] private[this] val vt2: Int
-[inaccessible] private[this] var rb2: Int
-[inaccessible] private[this] var rt2: Int
+retrieved 37 members
abstract class Base1 extends AnyRef
abstract trait Trait1 extends AnyRef
class Cb1 extends AnyRef
diff --git a/test/files/presentation/scope-completion-import.check b/test/files/presentation/scope-completion-import.check
index 220ffc399b..50197e5822 100644
--- a/test/files/presentation/scope-completion-import.check
+++ b/test/files/presentation/scope-completion-import.check
@@ -3,10 +3,8 @@ reload: Completions.scala
askScopeCompletion at Completions.scala(23,4)
================================================================================
[response] askScopeCompletion at (23,4)
-retrieved 18 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 16 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
@@ -27,10 +25,8 @@ val o: test.O.type
askScopeCompletion at Completions.scala(27,4)
================================================================================
[response] askScopeCompletion at (27,4)
-retrieved 17 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 15 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
@@ -126,10 +122,8 @@ val c: test.C
askScopeCompletion at Completions.scala(49,4)
================================================================================
[response] askScopeCompletion at (49,4)
-retrieved 18 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 16 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
@@ -150,10 +144,8 @@ private[this] var rOOO: Int
askScopeCompletion at Completions.scala(59,4)
================================================================================
[response] askScopeCompletion at (59,4)
-retrieved 19 members
-[inaccessible] private[this] val pVCCC: Int
+retrieved 17 members
[inaccessible] private[this] val pVOOO: Int
-[inaccessible] private[this] var pRCCC: Int
[inaccessible] private[this] var pROOO: Int
class C extends AnyRef
class Foo extends AnyRef
diff --git a/test/files/presentation/visibility.check b/test/files/presentation/visibility.check
index 1ae1213f2d..b77887f8f7 100644
--- a/test/files/presentation/visibility.check
+++ b/test/files/presentation/visibility.check
@@ -79,8 +79,7 @@ protected[package lang] def finalize(): Unit
askTypeCompletion at Completions.scala(22,11)
================================================================================
[response] askTypeCompletion at (22,11)
-retrieved 35 members
-[inaccessible] private def secretPrivate(): Unit
+retrieved 34 members
def +(other: String): String
def ->[B](y: B): (accessibility.AccessibilityChecks, B)
def ensuring(cond: Boolean): accessibility.AccessibilityChecks
diff --git a/test/files/run/reflection-magicsymbols-invoke.check b/test/files/run/reflection-magicsymbols-invoke.check
index 037ba33d21..b153ae0470 100644
--- a/test/files/run/reflection-magicsymbols-invoke.check
+++ b/test/files/run/reflection-magicsymbols-invoke.check
@@ -80,7 +80,6 @@ Array
it's important to print the list of Array's members
if some of them change (possibly, adding and/or removing magic symbols), we must update this test
constructor Array: (_length: Int)Array[T]
-constructor Cloneable: ()java.lang.Cloneable
method !=: (x$1: Any)Boolean
method ##: ()Int
method $asInstanceOf: [T0]()T0
diff --git a/test/files/run/reflection-sorted-members.check b/test/files/run/reflection-sorted-members.check
index c148e19e69..415e073149 100644
--- a/test/files/run/reflection-sorted-members.check
+++ b/test/files/run/reflection-sorted-members.check
@@ -1,4 +1,3 @@
value a
value b
value c
-value x
diff --git a/test/files/run/t261.check b/test/files/run/t261.check
new file mode 100644
index 0000000000..35d242ba79
--- /dev/null
+++ b/test/files/run/t261.check
@@ -0,0 +1,2 @@
+A
+B
diff --git a/test/files/run/t261.scala b/test/files/run/t261.scala
new file mode 100644
index 0000000000..d8ddb28c00
--- /dev/null
+++ b/test/files/run/t261.scala
@@ -0,0 +1,11 @@
+trait A { val foo: String = "A" }
+trait B {
+ private val foo: String = "B"
+ def f = println(foo)
+}
+object Test extends A with B {
+ def main(args: Array[String]) = {
+ println(foo)
+ f
+ }
+} \ No newline at end of file
diff --git a/test/files/run/t7475b.check b/test/files/run/t7475b.check
new file mode 100644
index 0000000000..51993f072d
--- /dev/null
+++ b/test/files/run/t7475b.check
@@ -0,0 +1,2 @@
+2
+2
diff --git a/test/files/run/t7475b.scala b/test/files/run/t7475b.scala
new file mode 100644
index 0000000000..a205602b6d
--- /dev/null
+++ b/test/files/run/t7475b.scala
@@ -0,0 +1,11 @@
+trait A { private val x = 1 }
+trait B { val x = 2 }
+trait C1 extends B with A { println(x) }
+trait C2 extends A with B { println(x) }
+
+object Test {
+ def main(args: Array[String]): Unit = {
+ new C1 { }
+ new C2 { }
+ }
+}
diff --git a/test/files/run/t7507.scala b/test/files/run/t7507.scala
index 6c1959ddac..a5eab6248f 100644
--- a/test/files/run/t7507.scala
+++ b/test/files/run/t7507.scala
@@ -4,6 +4,10 @@ trait Cake extends Slice
trait Slice { self: Cake => // must have self type that extends `Slice`
private[this] val bippy = () // must be private[this]
locally(bippy)
+ class C1 {
+ locally(bippy)
+ locally(self.bippy)
+ }
}
// Originally reported bug:
diff --git a/test/files/scalacheck/range.scala b/test/files/scalacheck/range.scala
index 1eb186f303..493083a51f 100644
--- a/test/files/scalacheck/range.scala
+++ b/test/files/scalacheck/range.scala
@@ -265,7 +265,8 @@ object TooLargeRange extends Properties("Too Large Range") {
property("Too large range throws exception") = forAll(genTooLargeStart) { start =>
try {
val r = Range.inclusive(start, Int.MaxValue, 1)
- println("how here? r = " + r.toString)
+ val l = r.length
+ println("how here? length = " + l + ", r = " + r.toString)
false
}
catch { case _: IllegalArgumentException => true }
diff --git a/test/junit/scala/collection/NumericRangeTest.scala b/test/junit/scala/collection/NumericRangeTest.scala
index 0260723b9d..3980c31577 100644
--- a/test/junit/scala/collection/NumericRangeTest.scala
+++ b/test/junit/scala/collection/NumericRangeTest.scala
@@ -6,7 +6,7 @@ import org.junit.Test
import scala.math._
import scala.util._
-/* Tests various maps by making sure they all agree on the same answers. */
+/* Tests various ranges by making sure they all agree on the same answers. */
@RunWith(classOf[JUnit4])
class RangeConsistencyTest {
def r2nr[T: Integral](
@@ -120,4 +120,21 @@ class RangeConsistencyTest {
case _ => false
}
}}
+
+ @Test
+ def testSI6736() {
+ // These operations on overfull ranges should all succeed.
+ assert( (0 to Int.MaxValue).contains(4) )
+ assert( !((Int.MinValue to 0).contains(4)) )
+ assert( (Int.MinValue to 0).last == 0 )
+ assert( (Int.MinValue until 5).last == 4 )
+ assert( (-7 to -99 by -4).last == -99 && (-7 until -99 by -4).last == -95 )
+ assert( (Int.MinValue to 5) == (Int.MinValue until 6) )
+ assert( (-3 to Int.MaxValue).drop(4).length == Int.MaxValue )
+ assert( (-3 to Int.MaxValue).take(1234) == (-3 to 1230) )
+ assert( (-3 to Int.MaxValue).dropRight(4).length == Int.MaxValue )
+ assert( (-3 to Int.MaxValue).takeRight(1234).length == 1234 )
+ assert( (-3 to Int.MaxValue).dropWhile(_ <= 0).length == Int.MaxValue )
+ assert( (-3 to Int.MaxValue).span(_ <= 0) match { case (a,b) => a.length == 4 && b.length == Int.MaxValue } )
+ }
}
diff --git a/test/files/pos/t1786.scala b/test/pending/pos/t1786.scala
index 32d6c06f6e..6299eb9eae 100644
--- a/test/files/pos/t1786.scala
+++ b/test/pending/pos/t1786.scala
@@ -1,3 +1,11 @@
+/** This a consequence of the current type checking algorithm, where bounds are checked only after variables are instantiated.
+ * I believe this will change once we go to contraint-based type inference.
+ * Alternatively, we can pursue a more extensive fix to SI-6169
+ *
+ * The below code shows a compiler flaw in that the wildcard "_" as value for a bounded type parameter either
+ * breaks the boundary - as it result in Any - or doesn't evaluate to the boundary (as I'd hoped it to be).
+*/
+
class SomeClass(val intValue:Int)
class MyClass[T <: SomeClass](val myValue:T)
class Flooz[A >: Null <: SomeClass, T >: Null <: A](var value: T)
diff --git a/test/files/pos/t5459.scala b/test/pending/pos/t5459.scala
index 971e6f896d..971e6f896d 100644
--- a/test/files/pos/t5459.scala
+++ b/test/pending/pos/t5459.scala