From 129c9d2ca3fa244d9605e291264bf6dc10332186 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 8 Oct 2015 10:25:52 -0400 Subject: fix t7634 to work on Cygwin this was failing because the expected output was: res1: List[String] = List(shello, world.) but the actual output was: res1: List[String] = List(shello, world., Picked up _JAVA_OPTIONS: -Duser.home=y:\jenkins) but the "Picked up..." part caused partest's filters feature to ignore the entire line (it doesn't anchor matches to start of line.) This was a tough one to track down. --- test/files/run/t7634.check | 4 ++-- test/files/run/t7634.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'test/files') diff --git a/test/files/run/t7634.check b/test/files/run/t7634.check index 879aea67a2..43128cad95 100644 --- a/test/files/run/t7634.check +++ b/test/files/run/t7634.check @@ -1,6 +1,6 @@ -scala> .lines -res1: List[String] = List(shello, world.) +scala> .lines.foreach(println) +shello, world. scala> :quit diff --git a/test/files/run/t7634.scala b/test/files/run/t7634.scala index aeb6a5e671..9520931941 100644 --- a/test/files/run/t7634.scala +++ b/test/files/run/t7634.scala @@ -9,7 +9,7 @@ import scala.util.Properties.propOrElse object Test extends ReplTest { def java = propOrElse("javacmd", "java") def code = s""":sh $java -classpath $testOutput hello.Hello - |.lines""".stripMargin + |.lines.foreach(println)""".stripMargin } package hello { -- cgit v1.2.3 From 212da3d5be061e235c7ee179a96ffa7b41b7bead Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Wed, 21 Jan 2015 23:38:34 -0800 Subject: SI-4950 Test reduction A session test with extra filtering best expresses the intentions. No check file is required. --- test/files/run/t4950.check | 7 ------- test/files/run/t4950.scala | 24 ++++++++++++++++++------ 2 files changed, 18 insertions(+), 13 deletions(-) delete mode 100644 test/files/run/t4950.check (limited to 'test/files') diff --git a/test/files/run/t4950.check b/test/files/run/t4950.check deleted file mode 100644 index 8994441163..0000000000 --- a/test/files/run/t4950.check +++ /dev/null @@ -1,7 +0,0 @@ - -scala> val 1 = 2 -scala.MatchError: 2 (of class java.lang.Integer) - -scala> val List(1) = List(1) - -scala> :quit diff --git a/test/files/run/t4950.scala b/test/files/run/t4950.scala index cef06027bf..e34b2cf3f2 100644 --- a/test/files/run/t4950.scala +++ b/test/files/run/t4950.scala @@ -1,12 +1,24 @@ -import scala.tools.partest.ReplTest +import scala.tools.partest.SessionTest +import scala.PartialFunction.{ cond => when } + +object Elision { + val elideMsg = """ ... \d+ elided""".r +} + +object Test extends SessionTest { + import Elision._ -object Test extends ReplTest { // Filter out the abbreviated stacktrace "... X elided" // because the number seems to differ between versions/platforms/... - override def show = eval() filterNot (_ contains "elided") foreach println - def code = + def elided(s: String) = when(s) { case elideMsg() => true } + override def eval() = super.eval() filterNot elided + def session = """ -val 1 = 2 -val List(1) = List(1) +scala> val 1 = 2 +scala.MatchError: 2 (of class java.lang.Integer) + +scala> val List(1) = List(1) + +scala> :quit """ } -- cgit v1.2.3 From d6e759165e57a9d920e7008774a81e190be7edde Mon Sep 17 00:00:00 2001 From: jvican Date: Sun, 18 Oct 2015 21:09:02 +0200 Subject: [SI-9503] Deprecate scala.collection.immutable.PagedSeq --- src/library/scala/collection/immutable/PagedSeq.scala | 3 ++- test/files/run/t3647.check | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 test/files/run/t3647.check (limited to 'test/files') diff --git a/src/library/scala/collection/immutable/PagedSeq.scala b/src/library/scala/collection/immutable/PagedSeq.scala index a86d4b6746..982c10687c 100644 --- a/src/library/scala/collection/immutable/PagedSeq.scala +++ b/src/library/scala/collection/immutable/PagedSeq.scala @@ -23,6 +23,7 @@ import scala.reflect.ClassTag * `fromIterator` and `fromIterable` provide generalised instances of `PagedSeq` * @since 2.7 */ +@deprecated("This object will be moved to the scala-parser-combinators module", "2.11.8") object PagedSeq { final val UndeterminedEnd = Int.MaxValue @@ -126,7 +127,7 @@ import PagedSeq._ * @define mayNotTerminateInf * @define willNotTerminateInf */ -@deprecatedInheritance("The implementation details of paged sequences make inheriting from them unwise.", "2.11.0") +@deprecated("This class will be moved to the scala-parser-combinators module", "2.11.8") class PagedSeq[T: ClassTag] protected( more: (Array[T], Int, Int) => Int, first1: Page[T], diff --git a/test/files/run/t3647.check b/test/files/run/t3647.check new file mode 100644 index 0000000000..e5c1ee1701 --- /dev/null +++ b/test/files/run/t3647.check @@ -0,0 +1 @@ +warning: there were three deprecation warnings; re-run with -deprecation for details -- cgit v1.2.3 From 167f79ca1ee300860a4dfc570a03590496764f88 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Sat, 7 Nov 2015 17:30:26 -0500 Subject: less confusing wording for a dependent method type error note to reviewers: the error messages in this file are over the place about whether they're called "parameter sections", or "argument lists", or what, so there's no point in being picky about that here for context see SI-823 --- src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala | 2 +- test/files/neg/depmet_1.check | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'test/files') diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala index b0bd9977a8..727f09290a 100644 --- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala @@ -1190,7 +1190,7 @@ trait ContextErrors { def IllegalDependentMethTpeError(sym: Symbol)(context: Context) = { val errorAddendum = - ": parameter appears in the type of another parameter in the same section or an earlier one" + ": parameter may only be referenced in a subsequent parameter section" issueSymbolTypeError(sym, "illegal dependent method type" + errorAddendum)(context) } diff --git a/test/files/neg/depmet_1.check b/test/files/neg/depmet_1.check index 7a4f845fd5..15498568c5 100644 --- a/test/files/neg/depmet_1.check +++ b/test/files/neg/depmet_1.check @@ -1,7 +1,7 @@ -depmet_1.scala:2: error: illegal dependent method type: parameter appears in the type of another parameter in the same section or an earlier one +depmet_1.scala:2: error: illegal dependent method type: parameter may only be referenced in a subsequent parameter section def precise0(y: x.type)(x: String): Unit = {} ^ -depmet_1.scala:3: error: illegal dependent method type: parameter appears in the type of another parameter in the same section or an earlier one +depmet_1.scala:3: error: illegal dependent method type: parameter may only be referenced in a subsequent parameter section def precise1(x: String, y: x.type): Unit = {} ^ depmet_1.scala:4: error: not found: value y -- cgit v1.2.3 From 4c3e766ee17afdb44ceeeb764adc660e2a501e9f Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 11 Nov 2015 19:51:43 -0500 Subject: it's Scaladoc, not "ScalaDoc" or "Scala doc" renaming the existing ScalaDoc and ScalaDocReporter classes might break stuff, sadly, but at least we can fix the rest --- src/compiler/scala/tools/nsc/Global.scala | 2 +- src/compiler/scala/tools/nsc/Reporting.scala | 2 +- src/compiler/scala/tools/nsc/settings/Warnings.scala | 2 +- src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 6 +++--- src/interactive/scala/tools/nsc/interactive/Global.scala | 2 +- src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala | 4 ++-- src/scaladoc/scala/tools/nsc/doc/Settings.scala | 2 +- test/disabled/presentation/akka/src/akka/actor/Supervisor.scala | 2 +- test/files/neg/macro-without-xmacros-a.check | 2 +- test/files/neg/macro-without-xmacros-b.check | 2 +- test/files/neg/t6040.check | 2 +- test/files/neg/t6120.check | 2 +- test/files/neg/t6952.check | 2 +- test/files/neg/t8736-c.check | 2 +- test/scaladoc/resources/links.scala | 2 +- test/scaladoc/run/links.scala | 2 +- 16 files changed, 19 insertions(+), 19 deletions(-) (limited to 'test/files') diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 936bed7c8f..a618b080c8 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -231,7 +231,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter) /** Called from parser, which signals hereby that a method definition has been parsed. */ def signalParseProgress(pos: Position) {} - /** Called by ScalaDocAnalyzer when a doc comment has been parsed. */ + /** Called by ScaladocAnalyzer when a doc comment has been parsed. */ def signalParsedDocComment(comment: String, pos: Position) = { // TODO: this is all very broken (only works for scaladoc comments, not regular ones) // --> add hooks to parser and refactor Interactive global to handle comments directly diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala index 4e7a527a5a..e01c536ad1 100644 --- a/src/compiler/scala/tools/nsc/Reporting.scala +++ b/src/compiler/scala/tools/nsc/Reporting.scala @@ -78,7 +78,7 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w s"""| |This can be achieved by adding the import clause 'import $fqname' |or by setting the compiler option -language:$featureName. - |See the Scala docs for value $fqname for a discussion + |See the Scaladoc for value $fqname for a discussion |why the feature $req be explicitly enabled.""".stripMargin ) reportedFeature += featureTrait diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 59cc13c64e..f570037760 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -49,7 +49,7 @@ trait Warnings { val NullaryOverride = LintWarning("nullary-override", "Warn when non-nullary `def f()' overrides nullary `def f'.", true) val InferAny = LintWarning("infer-any", "Warn when a type argument is inferred to be `Any`.", true) val MissingInterpolator = LintWarning("missing-interpolator", "A string literal appears to be missing an interpolator id.") - val DocDetached = LintWarning("doc-detached", "A ScalaDoc comment appears to be detached from its element.") + val DocDetached = LintWarning("doc-detached", "A Scaladoc comment appears to be detached from its element.") val PrivateShadow = LintWarning("private-shadow", "A private field (or class parameter) shadows a superclass field.") val TypeParameterShadow = LintWarning("type-parameter-shadow", "A local type parameter shadows a type already in scope.") val PolyImplicitOverload = LintWarning("poly-implicit-overload", "Parameterized overloaded implicit methods are not visible as view bounds.") diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 494e1e49b7..509ce59104 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -588,10 +588,10 @@ trait Implicits { if (Statistics.canEnable) Statistics.incCounter(matchingImplicits) // workaround for deficient context provided by ModelFactoryImplicitSupport#makeImplicitConstraints - val isScalaDoc = context.tree == EmptyTree + val isScaladoc = context.tree == EmptyTree val itree0 = atPos(pos.focus) { - if (isLocalToCallsite && !isScalaDoc) { + if (isLocalToCallsite && !isScaladoc) { // SI-4270 SI-5376 Always use an unattributed Ident for implicits in the local scope, // rather than an attributed Select, to detect shadowing. Ident(info.name) @@ -628,7 +628,7 @@ trait Implicits { // for instance, if we have `class C[T]` and `implicit def conv[T: Numeric](c: C[T]) = ???` // then Scaladoc will give us something of type `C[T]`, and it would like to know // that `conv` is potentially available under such and such conditions - case tree if isImplicitMethodType(tree.tpe) && !isScalaDoc => + case tree if isImplicitMethodType(tree.tpe) && !isScaladoc => applyImplicitArgs(tree) case tree => tree } diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala index 6600fea2d8..27a02c46a2 100644 --- a/src/interactive/scala/tools/nsc/interactive/Global.scala +++ b/src/interactive/scala/tools/nsc/interactive/Global.scala @@ -80,7 +80,7 @@ trait InteractiveAnalyzer extends Analyzer { val existingDerivedSym = owningInfo.decl(sym.name.toTermName).filter(sym => sym.isSynthetic && sym.isMethod) existingDerivedSym.alternatives foreach (owningInfo.decls.unlink) val defTree = tree match { - case dd: DocDef => dd.definition // See SI-9011, Scala IDE's presentation compiler incorporates ScalaDocGlobal with InterativeGlobal, so we have to unwrap DocDefs. + case dd: DocDef => dd.definition // See SI-9011, Scala IDE's presentation compiler incorporates ScaladocGlobal with InteractiveGlobal, so we have to unwrap DocDefs. case _ => tree } enterImplicitWrapper(defTree.asInstanceOf[ClassDef]) diff --git a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala index cbf8ff22ba..8ea8c4deff 100644 --- a/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala +++ b/src/scaladoc/scala/tools/nsc/doc/ScaladocAnalyzer.scala @@ -125,9 +125,9 @@ abstract class ScaladocSyntaxAnalyzer[G <: Global](val global: G) extends Syntax } else if (in.ch == '*') { docBuffer = null in.next - val scalaDoc = ("/**", "*/") + val scaladoc = ("/**", "*/") if (in.ch == '*') - docBuffer = new StringBuilder(scalaDoc._1) + docBuffer = new StringBuilder(scaladoc._1) do { do { if (in.ch != '*' && in.ch != SU) { diff --git a/src/scaladoc/scala/tools/nsc/doc/Settings.scala b/src/scaladoc/scala/tools/nsc/doc/Settings.scala index 067b2b2c29..90efa4e595 100644 --- a/src/scaladoc/scala/tools/nsc/doc/Settings.scala +++ b/src/scaladoc/scala/tools/nsc/doc/Settings.scala @@ -45,7 +45,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) val docfooter = StringSetting ( "-doc-footer", "footer", - "A footer on every ScalaDoc page, by default the EPFL/Typesafe copyright notice. Can be overridden with a custom footer.", + "A footer on every Scaladoc page, by default the EPFL/Typesafe copyright notice. Can be overridden with a custom footer.", "" ) diff --git a/test/disabled/presentation/akka/src/akka/actor/Supervisor.scala b/test/disabled/presentation/akka/src/akka/actor/Supervisor.scala index 4a1309faef..bec3c83f1a 100644 --- a/test/disabled/presentation/akka/src/akka/actor/Supervisor.scala +++ b/test/disabled/presentation/akka/src/akka/actor/Supervisor.scala @@ -95,7 +95,7 @@ case class SupervisorFactory(val config: SupervisorConfig) { * wire the children together using 'link', 'spawnLink' etc. and set the 'trapExit' flag in the * children that should trap error signals and trigger restart. *

- * See the ScalaDoc for the SupervisorFactory for an example on how to declaratively wire up children. + * See the Scaladoc for the SupervisorFactory for an example on how to declaratively wire up children. * * @author Jonas Bonér */ diff --git a/test/files/neg/macro-without-xmacros-a.check b/test/files/neg/macro-without-xmacros-a.check index ec194be3a9..65445d80dd 100644 --- a/test/files/neg/macro-without-xmacros-a.check +++ b/test/files/neg/macro-without-xmacros-a.check @@ -2,7 +2,7 @@ Macros_2.scala:5: error: macro definition needs to be enabled by making the implicit value scala.language.experimental.macros visible. This can be achieved by adding the import clause 'import scala.language.experimental.macros' or by setting the compiler option -language:experimental.macros. -See the Scala docs for value scala.language.experimental.macros for a discussion +See the Scaladoc for value scala.language.experimental.macros for a discussion why the feature needs to be explicitly enabled. def foo(x: Int): Int = macro foo_impl ^ diff --git a/test/files/neg/macro-without-xmacros-b.check b/test/files/neg/macro-without-xmacros-b.check index c97850f0a9..e3c1010d50 100644 --- a/test/files/neg/macro-without-xmacros-b.check +++ b/test/files/neg/macro-without-xmacros-b.check @@ -2,7 +2,7 @@ Macros_2.scala:3: error: macro definition needs to be enabled by making the implicit value scala.language.experimental.macros visible. This can be achieved by adding the import clause 'import scala.language.experimental.macros' or by setting the compiler option -language:experimental.macros. -See the Scala docs for value scala.language.experimental.macros for a discussion +See the Scaladoc for value scala.language.experimental.macros for a discussion why the feature needs to be explicitly enabled. def foo(x: Int): Int = macro Impls.foo_impl ^ diff --git a/test/files/neg/t6040.check b/test/files/neg/t6040.check index 16c90ede7e..350f796d18 100644 --- a/test/files/neg/t6040.check +++ b/test/files/neg/t6040.check @@ -2,7 +2,7 @@ t6040.scala:1: error: extension of type scala.Dynamic needs to be enabled by making the implicit value scala.language.dynamics visible. This can be achieved by adding the import clause 'import scala.language.dynamics' or by setting the compiler option -language:dynamics. -See the Scala docs for value scala.language.dynamics for a discussion +See the Scaladoc for value scala.language.dynamics for a discussion why the feature needs to be explicitly enabled. class X extends Dynamic ^ diff --git a/test/files/neg/t6120.check b/test/files/neg/t6120.check index a7d17e29cf..f432fde32f 100644 --- a/test/files/neg/t6120.check +++ b/test/files/neg/t6120.check @@ -2,7 +2,7 @@ t6120.scala:5: warning: postfix operator bippy should be enabled by making the implicit value scala.language.postfixOps visible. This can be achieved by adding the import clause 'import scala.language.postfixOps' or by setting the compiler option -language:postfixOps. -See the Scala docs for value scala.language.postfixOps for a discussion +See the Scaladoc for value scala.language.postfixOps for a discussion why the feature should be explicitly enabled. def f = null == null bippy ^ diff --git a/test/files/neg/t6952.check b/test/files/neg/t6952.check index 1a591d02c6..acee0e7d60 100644 --- a/test/files/neg/t6952.check +++ b/test/files/neg/t6952.check @@ -2,7 +2,7 @@ t6952.scala:2: error: extension of type scala.Dynamic needs to be enabled by making the implicit value scala.language.dynamics visible. This can be achieved by adding the import clause 'import scala.language.dynamics' or by setting the compiler option -language:dynamics. -See the Scala docs for value scala.language.dynamics for a discussion +See the Scaladoc for value scala.language.dynamics for a discussion why the feature needs to be explicitly enabled. trait B extends Dynamic ^ diff --git a/test/files/neg/t8736-c.check b/test/files/neg/t8736-c.check index 06b2228543..7debb6d515 100644 --- a/test/files/neg/t8736-c.check +++ b/test/files/neg/t8736-c.check @@ -2,7 +2,7 @@ t8736-c.scala:4: warning: higher-kinded type should be enabled by making the implicit value scala.language.higherKinds visible. This can be achieved by adding the import clause 'import scala.language.higherKinds' or by setting the compiler option -language:higherKinds. -See the Scala docs for value scala.language.higherKinds for a discussion +See the Scaladoc for value scala.language.higherKinds for a discussion why the feature should be explicitly enabled. def hk[M[_]] = ??? ^ diff --git a/test/scaladoc/resources/links.scala b/test/scaladoc/resources/links.scala index ecac9c63cf..8e000ab979 100644 --- a/test/scaladoc/resources/links.scala +++ b/test/scaladoc/resources/links.scala @@ -1,6 +1,6 @@ // that would be: // SI-5079 "Scaladoc can't link to an object (only a class or trait)" -// SI-4497 "Links in ScalaDoc - Spec and implementation unsufficient" +// SI-4497 "Links in Scaladoc - Spec and implementation unsufficient" // SI-4224 "Wiki-links should support method targets" // SI-3695 "support non-fully-qualified type links in scaladoc comments" // SI-6487 "Scaladoc can't link to inner classes" diff --git a/test/scaladoc/run/links.scala b/test/scaladoc/run/links.scala index 64441c2d95..01db66aec3 100644 --- a/test/scaladoc/run/links.scala +++ b/test/scaladoc/run/links.scala @@ -3,7 +3,7 @@ import scala.tools.nsc.doc.model._ import scala.tools.partest.ScaladocModelTest // SI-5079 "Scaladoc can't link to an object (only a class or trait)" -// SI-4497 "Links in ScalaDoc - Spec and implementation unsufficient" +// SI-4497 "Links in Scaladoc - Spec and implementation unsufficient" // SI-4224 "Wiki-links should support method targets" // SI-3695 "support non-fully-qualified type links in scaladoc comments" // SI-6487 "Scaladoc can't link to inner classes" -- cgit v1.2.3 From 238b1fba3d5085457d05817c646d436542def5ea Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Thu, 29 Oct 2015 13:01:07 +1000 Subject: Attacking exponential complexity in TypeMaps - Don't normalize existentials during the `contain`-s type map; `ExistentialType#normalize' calls contains internally and an exponential blowup ensues. - Ensure that the type map used in variance validation never returns modified types in order to avoid needless cloning of symbols. The enclosed test case still gets stuck in Uncurry, thanks to the way that `TypeMap#mapOver(List[Symbol])` recurses through the type first to check whether the type map would be an no-op or not. If not, it repeats the type map with cloned symbols. Doing the work twice at each level of recursion blows up the complexity. Removing that "fast path" allows the enclosed test to compile completely. As at this commit, it gets stuck in uncurry, which dealiases `s.List` to `s.c.i.List` within the type. Some more background on the troublesome part of `TypeMap`: http://lrytz.github.io/scala-aladdin-bugtracker/displayItem.do%3Fid=1210.html https://github.com/scala/scala/commit/f8b2b21050e7a2ca0f537ef70e3e0c8eead43abc --- src/reflect/scala/reflect/internal/Variances.scala | 24 ++++++++++++++-------- .../scala/reflect/internal/tpe/TypeMaps.scala | 18 ++++++++++++---- test/files/pos/existental-slow-compile2.scala | 7 +++++++ test/files/pos/existential-slow-compile1.flags | 1 + test/files/pos/existential-slow-compile1.scala | 7 +++++++ 5 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 test/files/pos/existental-slow-compile2.scala create mode 100644 test/files/pos/existential-slow-compile1.flags create mode 100644 test/files/pos/existential-slow-compile1.scala (limited to 'test/files') diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala index ef22df3f2e..af04f47e0e 100644 --- a/src/reflect/scala/reflect/internal/Variances.scala +++ b/src/reflect/scala/reflect/internal/Variances.scala @@ -122,15 +122,21 @@ trait Variances { * same is true of the parameters (ValDefs) unless we are inside a * refinement, in which case they are checked from here. */ - def apply(tp: Type): Type = tp match { - case _ if isUncheckedVariance(tp) => tp - case _ if resultTypeOnly(tp) => this(tp.resultType) - case TypeRef(_, sym, _) if sym.isAliasType => this(tp.normalize) - case TypeRef(_, sym, _) if !sym.variance.isInvariant => checkVarianceOfSymbol(sym) ; mapOver(tp) - case RefinedType(_, _) => withinRefinement(mapOver(tp)) - case ClassInfoType(parents, _, _) => parents foreach this ; tp - case mt @ MethodType(_, result) => flipped(mt.paramTypes foreach this) ; this(result) - case _ => mapOver(tp) + def apply(tp: Type): Type = { + tp match { + case _ if isUncheckedVariance(tp) => + case _ if resultTypeOnly(tp) => this(tp.resultType) + case TypeRef(_, sym, _) if sym.isAliasType => this(tp.normalize) + case TypeRef(_, sym, _) if !sym.variance.isInvariant => checkVarianceOfSymbol(sym) ; mapOver(tp) + case RefinedType(_, _) => withinRefinement(mapOver(tp)) + case ClassInfoType(parents, _, _) => parents foreach this + case mt @ MethodType(_, result) => flipped(mt.paramTypes foreach this) ; this(result) + case _ => mapOver(tp) + } + // We're using TypeMap here for type traversal only. To avoid wasteful symbol + // cloning during the recursion, it is important to return the input `tp`, rather + // than the result of the pattern match above, which normalizes types. + tp } def validateDefinition(base: Symbol) { val saved = this.base diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala index b8d4050d7d..804360b677 100644 --- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala +++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala @@ -998,10 +998,20 @@ private[internal] trait TypeMaps { class ContainsCollector(sym: Symbol) extends TypeCollector(false) { def traverse(tp: Type) { if (!result) { - tp.normalize match { - case TypeRef(_, sym1, _) if (sym == sym1) => result = true - case SingleType(_, sym1) if (sym == sym1) => result = true - case _ => mapOver(tp) + tp match { + case _: ExistentialType => + // ExistentialType#normalize internally calls contains, which leads to exponential performance + // for types like: `A[_ <: B[_ <: ... ]]`. Example: pos/existential-contains.scala. + // + // We can just map over the components and wait until we see the underlying type before we call + // normalize. + mapOver(tp) + case _ => + tp.normalize match { + case TypeRef(_, sym1, _) if (sym == sym1) => result = true + case SingleType(_, sym1) if (sym == sym1) => result = true + case _ => mapOver(tp) + } } } } diff --git a/test/files/pos/existental-slow-compile2.scala b/test/files/pos/existental-slow-compile2.scala new file mode 100644 index 0000000000..907344982c --- /dev/null +++ b/test/files/pos/existental-slow-compile2.scala @@ -0,0 +1,7 @@ +class C { + class L[+A] + def test = { + val foo: + L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: _ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: _ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_]]]]]]]]]]]]]]]]]]]]]]]] + = ??? } } + diff --git a/test/files/pos/existential-slow-compile1.flags b/test/files/pos/existential-slow-compile1.flags new file mode 100644 index 0000000000..7f7581974d --- /dev/null +++ b/test/files/pos/existential-slow-compile1.flags @@ -0,0 +1 @@ +-Ystop-after:refchecks diff --git a/test/files/pos/existential-slow-compile1.scala b/test/files/pos/existential-slow-compile1.scala new file mode 100644 index 0000000000..8602afd9db --- /dev/null +++ b/test/files/pos/existential-slow-compile1.scala @@ -0,0 +1,7 @@ +class C { + type L[+A] = scala.collection.immutable.List[A] + def test = { + val foo: + L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: _ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: _ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_ <: L[_]]]]]]]]]]]]]]]]]]]]]]]] + = ??? } } + -- cgit v1.2.3