diff options
Diffstat (limited to 'src')
12 files changed, 93 insertions, 68 deletions
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 0536be92cf..3590254128 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -438,6 +438,17 @@ class MutableSettings(val errorFn: String => Unit) override def tryToSetFromPropertyValue(s : String) { // used from ide value = s.equalsIgnoreCase("true") } + override def tryToSetColon(args: List[String]) = args match { + case Nil => tryToSet(Nil) + case List(x) => + if (x.equalsIgnoreCase("true")) { + value = true + Some(Nil) + } else if (x.equalsIgnoreCase("false")) { + value = false + Some(Nil) + } else errorAndValue("'" + x + "' is not a valid choice for '" + name + "'", None) + } } /** A special setting for accumulating arguments like -Dfoo=bar. */ @@ -668,4 +679,14 @@ class MutableSettings(val errorFn: String => Unit) else name + "[:phases]" ) } + + /** Internal use - syntax enhancements. */ + protected class EnableSettings[T <: BooleanSetting](val s: T) { + def enablingIfNotSetByUser(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (sett => if (!sett.isSetByUser) sett.value = s.value)) + def enabling(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (_.value = s.value)) + def disabling(toDisable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toDisable foreach (_.value = !s.value)) + def andThen(f: s.T => Unit): s.type = s withPostSetHook (setting => f(setting.value)) + } + import scala.language.implicitConversions + protected implicit def installEnableSettings[T <: BooleanSetting](s: T): EnableSettings[T] = new EnableSettings(s) } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index a385a31165..a643a08614 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -20,7 +20,7 @@ trait ScalaSettings extends AbsScalaSettings self: MutableSettings => /** Set of settings */ - protected lazy val allSettings = mutable.HashSet[Setting]() + protected[scala] lazy val allSettings = mutable.HashSet[Setting]() /** Against my better judgment, giving in to martin here and allowing * CLASSPATH to be used automatically. So for the user-specified part @@ -47,14 +47,6 @@ trait ScalaSettings extends AbsScalaSettings /** Is an info setting set? */ def isInfo = infoSettings exists (_.isSetByUser) - /** Internal use - syntax enhancements. */ - private class EnableSettings[T <: BooleanSetting](val s: T) { - def enabling(toEnable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toEnable foreach (_.value = s.value)) - def disabling(toDisable: List[BooleanSetting]): s.type = s withPostSetHook (_ => toDisable foreach (_.value = !s.value)) - def andThen(f: s.T => Unit): s.type = s withPostSetHook (setting => f(setting.value)) - } - private implicit def installEnableSettings[T <: BooleanSetting](s: T) = new EnableSettings(s) - /** Disable a setting */ def disable(s: Setting) = allSettings -= s @@ -216,10 +208,10 @@ trait ScalaSettings extends AbsScalaSettings /** Groups of Settings. */ - val future = BooleanSetting("-Xfuture", "Turn on future language features.") enabling futureSettings - val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enabling optimiseSettings + val future = BooleanSetting("-Xfuture", "Turn on future language features.") enablingIfNotSetByUser futureSettings + val optimise = BooleanSetting("-optimise", "Generates faster bytecode by applying optimisations to the program") withAbbreviation "-optimize" enablingIfNotSetByUser optimiseSettings val nooptimise = BooleanSetting("-Ynooptimise", "Clears all the flags set by -optimise. Useful for testing optimizations in isolation.") withAbbreviation "-Ynooptimize" disabling optimise::optimiseSettings - val Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enabling experimentalSettings + val Xexperimental = BooleanSetting("-Xexperimental", "Enable experimental extensions.") enablingIfNotSetByUser experimentalSettings /** * Settings motivated by GenBCode diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 791d44153c..1509ad13b8 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -7,6 +7,8 @@ package scala.tools package nsc package settings +import language.existentials + /** Settings influencing the printing of warnings. */ trait Warnings { @@ -30,21 +32,10 @@ trait Warnings { warnNullaryUnit, warnAdaptedArgs, warnInferAny + // warnUnused SI-7712, SI-7707 warnUnused not quite ready for prime-time + // warnUnusedImport currently considered too noisy for general use ) - // Warning groups. - val lint = ( - BooleanSetting("-Xlint", "Enable recommended additional warnings.") - withPostSetHook (_ => lintWarnings foreach (_.value = true)) - ) - - /*val warnEverything = */ ( - BooleanSetting("-Ywarn-all", "Enable all -Y warnings.") - withPostSetHook { _ => - lint.value = true - allWarnings foreach (_.value = true) - } - ) private lazy val warnSelectNullable = BooleanSetting("-Xcheck-null", "This option is obsolete and does nothing.") // Individual warnings. @@ -56,6 +47,11 @@ trait Warnings { val warnInaccessible = BooleanSetting ("-Ywarn-inaccessible", "Warn about inaccessible types in method signatures.") val warnNullaryOverride = BooleanSetting ("-Ywarn-nullary-override", "Warn when non-nullary overrides nullary, e.g. `def foo()` over `def foo`.") val warnInferAny = BooleanSetting ("-Ywarn-infer-any", "Warn when a type argument is inferred to be `Any`.") + val warnUnused = BooleanSetting ("-Ywarn-unused", "Warn when local and private vals, vars, defs, and types are are unused") + val warnUnusedImport = BooleanSetting ("-Ywarn-unused-import", "Warn when imports are unused") + + // Warning groups. + val lint = BooleanSetting("-Xlint", "Enable recommended additional warnings.") enablingIfNotSetByUser lintWarnings // Backward compatibility. @deprecated("Use fatalWarnings", "2.11.0") def Xwarnfatal = fatalWarnings // used by sbt diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index eba2e1399d..bd2f6f0018 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -238,8 +238,11 @@ abstract class Erasure extends AddInterfaces if (!(AnyRefTpe <:< bounds.hi)) "+" + boxedSig(bounds.hi) else if (!(bounds.lo <:< NullTpe)) "-" + boxedSig(bounds.lo) else "*" - } else { - boxedSig(tp) + } else tp match { + case PolyType(_, res) => + "*" // SI-7932 + case _ => + boxedSig(tp) } def classSig = { val preRebound = pre.baseType(sym.owner) // #2585 diff --git a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala index 5c02516c47..323fe1c171 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Analyzer.scala @@ -102,7 +102,9 @@ trait Analyzer extends AnyRef unit.body = typer.typed(unit.body) if (global.settings.Yrangepos && !global.reporter.hasErrors) global.validatePositions(unit.body) for (workItem <- unit.toCheck) workItem() - if (settings.lint) + if (settings.warnUnusedImport) + warnUnusedImports(unit) + if (settings.warnUnused) typer checkUnused unit } finally { diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 6e9e16ffc9..98ee4ad94d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -1207,7 +1207,7 @@ trait Contexts { self: Analyzer => trait ImportContext extends Context { private val impInfo: ImportInfo = { val info = new ImportInfo(tree.asInstanceOf[Import], outerDepth) - if (settings.lint && !isRootImport) // excludes java.lang/scala/Predef imports + if (settings.warnUnusedImport && !isRootImport) // excludes java.lang/scala/Predef imports allImportInfos(unit) ::= info info } @@ -1316,7 +1316,7 @@ trait Contexts { self: Analyzer => if (result == NoSymbol) selectors = selectors.tail } - if (settings.lint && selectors.nonEmpty && result != NoSymbol && pos != NoPosition) + if (settings.warnUnusedImport && selectors.nonEmpty && result != NoSymbol && pos != NoPosition) recordUsage(current, result) // Harden against the fallout from bugs like SI-6745 diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index ca960d7b11..60346e7be1 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -518,8 +518,6 @@ trait TypeDiagnostics { } def apply(unit: CompilationUnit) = { - warnUnusedImports(unit) - val p = new UnusedPrivates p traverse unit.body val unused = p.unusedTerms diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala index 6ab76bce89..445edd23cb 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -29,6 +29,8 @@ import scala.annotation.unchecked.uncheckedVariance import scala.annotation.unchecked.uncheckedStable import scala.language.{ higherKinds, implicitConversions } +import scala.collection.parallel.ParallelCollectionImplicits._ + /** A template trait for parallel collections of type `ParIterable[T]`. * diff --git a/src/library/scala/collection/parallel/ParSeqLike.scala b/src/library/scala/collection/parallel/ParSeqLike.scala index ca21f24534..0b6fec364e 100644 --- a/src/library/scala/collection/parallel/ParSeqLike.scala +++ b/src/library/scala/collection/parallel/ParSeqLike.scala @@ -16,6 +16,7 @@ import scala.collection.generic.CanBuildFrom import scala.collection.generic.CanCombineFrom import scala.collection.generic.VolatileAbort +import scala.collection.parallel.ParallelCollectionImplicits._ /** A template trait for sequences of type `ParSeq[T]`, representing * parallel sequences with element type `T`. diff --git a/src/library/scala/collection/parallel/package.scala b/src/library/scala/collection/parallel/package.scala index 923e21e5a7..91c54fa8f1 100644 --- a/src/library/scala/collection/parallel/package.scala +++ b/src/library/scala/collection/parallel/package.scala @@ -53,43 +53,52 @@ package object parallel { c } - /* implicit conversions */ - - implicit def factory2ops[From, Elem, To](bf: CanBuildFrom[From, Elem, To]) = new FactoryOps[From, Elem, To] { - def isParallel = bf.isInstanceOf[Parallel] - def asParallel = bf.asInstanceOf[CanCombineFrom[From, Elem, To]] - def ifParallel[R](isbody: CanCombineFrom[From, Elem, To] => R) = new Otherwise[R] { - def otherwise(notbody: => R) = if (isParallel) isbody(asParallel) else notbody - } - } - implicit def traversable2ops[T](t: scala.collection.GenTraversableOnce[T]) = new TraversableOps[T] { - def isParallel = t.isInstanceOf[Parallel] - def isParIterable = t.isInstanceOf[ParIterable[_]] - def asParIterable = t.asInstanceOf[ParIterable[T]] - def isParSeq = t.isInstanceOf[ParSeq[_]] - def asParSeq = t.asInstanceOf[ParSeq[T]] - def ifParSeq[R](isbody: ParSeq[T] => R) = new Otherwise[R] { - def otherwise(notbody: => R) = if (isParallel) isbody(asParSeq) else notbody - } - def toParArray = if (t.isInstanceOf[ParArray[_]]) t.asInstanceOf[ParArray[T]] else { - val it = t.toIterator - val cb = mutable.ParArrayCombiner[T]() - while (it.hasNext) cb += it.next - cb.result - } - } - implicit def throwable2ops(self: Throwable) = new ThrowableOps { - def alongWith(that: Throwable) = (self, that) match { - case (self: CompositeThrowable, that: CompositeThrowable) => new CompositeThrowable(self.throwables ++ that.throwables) - case (self: CompositeThrowable, _) => new CompositeThrowable(self.throwables + that) - case (_, that: CompositeThrowable) => new CompositeThrowable(that.throwables + self) - case _ => new CompositeThrowable(Set(self, that)) + /** Adds toParArray method to collection classes. */ + implicit class CollectionsHaveToParArray[C, T](c: C)(implicit asGto: C => scala.collection.GenTraversableOnce[T]) { + def toParArray = { + val t = asGto(c) + if (t.isInstanceOf[ParArray[_]]) t.asInstanceOf[ParArray[T]] + else { + val it = t.toIterator + val cb = mutable.ParArrayCombiner[T]() + while (it.hasNext) cb += it.next + cb.result + } } } } package parallel { + /** Implicit conversions used in the implementation of parallel collections. */ + private[collection] object ParallelCollectionImplicits { + implicit def factory2ops[From, Elem, To](bf: CanBuildFrom[From, Elem, To]) = new FactoryOps[From, Elem, To] { + def isParallel = bf.isInstanceOf[Parallel] + def asParallel = bf.asInstanceOf[CanCombineFrom[From, Elem, To]] + def ifParallel[R](isbody: CanCombineFrom[From, Elem, To] => R) = new Otherwise[R] { + def otherwise(notbody: => R) = if (isParallel) isbody(asParallel) else notbody + } + } + implicit def traversable2ops[T](t: scala.collection.GenTraversableOnce[T]) = new TraversableOps[T] { + def isParallel = t.isInstanceOf[Parallel] + def isParIterable = t.isInstanceOf[ParIterable[_]] + def asParIterable = t.asInstanceOf[ParIterable[T]] + def isParSeq = t.isInstanceOf[ParSeq[_]] + def asParSeq = t.asInstanceOf[ParSeq[T]] + def ifParSeq[R](isbody: ParSeq[T] => R) = new Otherwise[R] { + def otherwise(notbody: => R) = if (isParallel) isbody(asParSeq) else notbody + } + } + implicit def throwable2ops(self: Throwable) = new ThrowableOps { + def alongWith(that: Throwable) = (self, that) match { + case (self: CompositeThrowable, that: CompositeThrowable) => new CompositeThrowable(self.throwables ++ that.throwables) + case (self: CompositeThrowable, _) => new CompositeThrowable(self.throwables + that) + case (_, that: CompositeThrowable) => new CompositeThrowable(that.throwables + self) + case _ => new CompositeThrowable(Set(self, that)) + } + } + } + trait FactoryOps[From, Elem, To] { trait Otherwise[R] { def otherwise(notbody: => R): R @@ -111,7 +120,6 @@ package parallel { def isParSeq: Boolean def asParSeq: ParSeq[T] def ifParSeq[R](isbody: ParSeq[T] => R): Otherwise[R] - def toParArray: ParArray[T] } @deprecated("This trait will be removed.", "2.11.0") diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index ca43fdcb63..3bcfed7d34 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -65,10 +65,11 @@ trait Variances { * The search proceeds from `base` to the owner of `tvar`. * Initially the state is covariant, but it might change along the search. * - * An alias which does not override anything is treated as Bivariant; + * A local alias type is treated as Bivariant; * this is OK because we always expand aliases for variance checking. - * However if it does override a type in a base class, we must assume Invariant - * because there may be references to the type parameter that are not checked. + * However, for an alias which might be externally visible, we must assume Invariant, + * because there may be references to the type parameter that are not checked, + * leading to unsoundness (see SI-6566). */ def relativeVariance(tvar: Symbol): Variance = { def nextVariance(sym: Symbol, v: Variance): Variance = ( diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index 6d83032c2d..f06420de96 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -667,7 +667,8 @@ private[internal] trait TypeMaps { /** A base class to compute all substitutions */ abstract class SubstMap[T](from: List[Symbol], to: List[T]) extends TypeMap { - assert(sameLength(from, to), "Unsound substitution from "+ from +" to "+ to) + // OPT this check was 2-3% of some profiles, demoted to -Xdev + if (isDeveloper) assert(sameLength(from, to), "Unsound substitution from "+ from +" to "+ to) /** Are `sym` and `sym1` the same? Can be tuned by subclasses. */ protected def matches(sym: Symbol, sym1: Symbol): Boolean = sym eq sym1 |