summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--project/Build.scala11
-rw-r--r--project/Layers.scala7
-rw-r--r--project/Partest.scala2
-rw-r--r--project/Release.scala106
-rw-r--r--project/ShaResolve.scala2
-rw-r--r--project/Versions.scala142
-rw-r--r--project/project/Build.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala5
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala5
-rw-r--r--src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala80
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala8
-rw-r--r--src/partest/scala/tools/partest/nest/SBTRunner.scala18
-rw-r--r--test/files/pos/t4651.scala12
-rw-r--r--test/files/run/t3702.check2
-rw-r--r--test/files/run/t3702.scala11
-rw-r--r--test/files/run/t4482.check1
-rw-r--r--test/files/run/t4482.scala15
-rw-r--r--test/pending/pos/t1832.scala10
-rw-r--r--test/pending/pos/t3439.scala2
-rw-r--r--test/pending/pos/t4717.scala10
-rw-r--r--test/pending/pos/t5091.scala11
-rw-r--r--test/pending/pos/t5231.scala18
-rw-r--r--test/pending/pos/t5265.scala21
31 files changed, 374 insertions, 159 deletions
diff --git a/project/Build.scala b/project/Build.scala
index 25fb31cf5b..ea0e84f0cc 100644
--- a/project/Build.scala
+++ b/project/Build.scala
@@ -23,7 +23,7 @@ object ScalaBuild extends Build with Layers {
lazy val buildFixed = AttributeKey[Boolean]("build-uri-fixed")
// Build wide settings:
- override lazy val settings = super.settings ++ Seq(
+ override lazy val settings = super.settings ++ Versions.settings ++ Seq(
autoScalaLibrary := false,
resolvers += Resolver.url(
"Typesafe nightlies",
@@ -34,7 +34,7 @@ object ScalaBuild extends Build with Layers {
ScalaToolsSnapshots
),
organization := "org.scala-lang",
- version := "2.10.0-SNAPSHOT",
+ version <<= Versions.mavenVersion,
pomExtra := <xml:group>
<inceptionYear>2002</inceptionYear>
<licenses>
@@ -148,13 +148,14 @@ object ScalaBuild extends Build with Layers {
lazy val externalDeps: Setting[_] = libraryDependencies <<= (sbtVersion)(v =>
Seq(
"org.apache.ant" % "ant" % "1.8.2",
- "org.scala-tools.sbt" % "compiler-interface" % v % "provided"
+ "org.scala-sbt" % "compiler-interface" % v % "provided"
)
)
// These are setting overrides for most artifacts in the Scala build file.
def settingOverrides: Seq[Setting[_]] = publishSettings ++ Seq(
crossPaths := false,
+ autoScalaLibrary := false,
publishArtifact in packageDoc := false,
publishArtifact in packageSrc := false,
target <<= (baseDirectory, name) apply (_ / "target" / _),
@@ -327,7 +328,7 @@ object ScalaBuild extends Build with Layers {
// Testing
// --------------------------------------------------------------
/* lazy val scalacheckSettings: Seq[Setting[_]] = Seq(fullQuickScalaReference, crossPaths := false)*/
- lazy val scalacheck = uri("git://github.com/rickynils/scalacheck.git")
+ lazy val scalacheck = uri("git://github.com/jsuereth/scalacheck.git#scala-build")
lazy val testsuiteSettings: Seq[Setting[_]] = compilerDependentProjectSettings ++ partestTaskSettings ++ VerifyClassLoad.settings ++ Seq(
unmanagedBase <<= baseDirectory / "test/files/lib",
@@ -518,7 +519,7 @@ object ScalaBuild extends Build with Layers {
// Add in some more dependencies
makeDistMappings <<= (makeDistMappings,
packageBin in swing in Compile) map {
- (dist, s, d) =>
+ (dist, s) =>
dist ++ Seq(s -> "lib/scala-swing.jar")
},
makeDist <<= (makeDistMappings, baseDirectory, streams) map { (maps, dir, s) =>
diff --git a/project/Layers.scala b/project/Layers.scala
index d39e58014c..3d6d780f8f 100644
--- a/project/Layers.scala
+++ b/project/Layers.scala
@@ -16,6 +16,8 @@ trait Layers extends Build {
def fjbg: Project
/** A setting that adds some external dependencies. */
def externalDeps: Setting[_]
+ /** The root project. */
+ def aaa_root: Project
/** Creates a reference Scala version that can be used to build other projects. This takes in the raw
* library, compiler and fjbg libraries as well as a string representing the layer name (used for compiling the compile-interface).
@@ -57,7 +59,7 @@ trait Layers extends Build {
// TODO - Allow other scalac option settings.
scalacOptions in Compile <++= (scalaSource in Compile) map (src => Seq("-sourcepath", src.getAbsolutePath)),
classpathOptions := ClasspathOptions.manual,
- resourceGenerators in Compile <+= (baseDirectory, version, resourceManaged, gitRunner, streams) map Release.generatePropertiesFile("library.properties"),
+ resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, skip in Compile, streams) map Versions.generateVersionPropertiesFile("library.properties"),
referenceScala
)
@@ -68,9 +70,8 @@ trait Layers extends Build {
resourceDirectory in Compile <<= baseDirectory apply (_ / "src" / "compiler"),
unmanagedSourceDirectories in Compile <+= (baseDirectory) apply (_ / "src" / "msil"),
defaultExcludes := ("tests"),
- javacOptions ++= Seq("-source", "1.4"),
defaultExcludes in unmanagedResources := "*.scala",
- resourceGenerators in Compile <+= (baseDirectory, version, resourceManaged, gitRunner, streams) map Release.generatePropertiesFile("compiler.properties"),
+ resourceGenerators in Compile <+= (resourceManaged, Versions.scalaVersions, skip in Compile, streams) map Versions.generateVersionPropertiesFile("compiler.properties"),
// Note, we might be able to use the default task, but for some reason ant was filtering files out. Not sure what's up, but we'll
// stick with that for now.
unmanagedResources in Compile <<= (baseDirectory) map {
diff --git a/project/Partest.scala b/project/Partest.scala
index ad8047fa00..bbc160a41d 100644
--- a/project/Partest.scala
+++ b/project/Partest.scala
@@ -115,7 +115,7 @@ object partest {
}
}
- def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: ScopedTask[Seq[String]]): Project.Initialize[Task[PartestRunner]] =
+ def partestRunnerTask(classpath: ScopedTask[Classpath], javacOptions: SettingKey[Seq[String]]): Project.Initialize[Task[PartestRunner]] =
(classpath, javacOptions) map ((cp, opts) => new PartestRunner(Build.data(cp), opts mkString " "))
}
diff --git a/project/Release.scala b/project/Release.scala
index 5ed77548fc..1a17956c13 100644
--- a/project/Release.scala
+++ b/project/Release.scala
@@ -1,115 +1,15 @@
import sbt._
import Keys._
-import _root_.com.jsuereth.git.GitRunner
object Release {
- // TODO - move more of the dist project over here...
+ // TODO - Just make the STARR artifacts and dump the sha1 files.
lazy val pushStarr = Command.command("push-starr") { (state: State) =>
- def f(s: Setting[_]): Setting[_] = s.key.key match {
- case version.key => // TODO - use full version
- s.asInstanceOf[Setting[String]].mapInit( (_,_) => timeFormat format (new java.util.Date))
- case organization.key =>
- s.asInstanceOf[Setting[String]].mapInit( (_,_) => "org.scala-lang.bootstrapp")
- // TODO - Switch publish repo to be typesafe starr repo.
- case publishTo.key =>
- s.asInstanceOf[Setting[Option[Resolver]]].mapInit((_,_) => Some("Starr Repo" at "http://typesafe.artifactoryonline.com/typesafe/starr-releases/"))
- case _ => s
- }
- val extracted = Project.extract(state)
- import extracted._
- // Swap version on projects
- val transformed = session.mergeSettings map ( s => f(s) )
- val newStructure = Load.reapply(transformed, structure)
- val newState = Project.setProject(session, newStructure, state)
- // TODO - Run tasks. Specifically, push scala-compiler + scala-library. *Then* bump the STARR version locally.
- // The final course of this command should be:
- // publish-local
- // Project.evaluateTask(publishLocal, newState)
- // bump STARR version setting
- // TODO - Define Task
- // Rebuild quick + test to ensure it works
- // Project.evaluateTask(test, newState)
- // push STARR remotely
- Project.evaluateTask(publish, newState)
+ // TODO do something
// Revert to previous project state.
- Project.setProject(session, structure, state)
+ state
}
- // TODO - Autocomplete
- /*lazy val setStarrHome = Command.single("set-starr-home") { (state: State, homeDir: String) =>
- def f(s: Setting[_]): Setting[_] =
- if(s.key.key == scalaInstance.key) {
- s.asInstanceOf[Setting[ScalaInstance]] mapInit { (key, value) =>
- if(value.version == "starr")
- scalaInstance <<= appConfiguration map { app =>
- val launcher = app.provider.scalaProvider.launcher
- ScalaInstance("starr", new File(homeDir), launcher)
- }
- else value
- }
- } else s
- val extracted = Project.extract(state)
- import extracted._
- val transformed = session.mergeSettings map f
- val newStructure = Load.reapply(transformed, structure)
- Project.setProject(session, newStructure, state)
- }*/
-
- lazy val timeFormat = {
- val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss")
- formatter.setTimeZone(java.util.TimeZone.getTimeZone("GMT"))
- formatter
- }
-
- /** This generates a properties file, if it does not already exist, with the maximum lastmodified timestamp
- * of any source file. */
- def generatePropertiesFile(name: String)(baseDirectory: File, version: String, dir: File, git: GitRunner, s: TaskStreams): Seq[File] = {
- // TODO - We can probably clean this up by moving caching bits elsewhere perhaps....
- val target = dir / name
- // TODO - Regenerate on triggers, like recompilation or something...
- val fullVersion = makeFullVersionString(baseDirectory, version, git, s)
- def hasSameVersion: Boolean = {
- val props = new java.util.Properties
- val in = new java.io.FileInputStream(target)
- try props.load(in) finally in.close()
- def withoutDate(s: String): String = s.reverse.dropWhile (_ != '.').reverse
- withoutDate(fullVersion) == withoutDate(props getProperty "version.number")
- }
- if (!target.exists || !hasSameVersion) {
- makePropertiesFile(target, fullVersion)
- }
- target :: Nil
- }
-
- // This creates the *.properties file used to determine the current version of scala at runtime. TODO - move these somewhere utility like.
- def makePropertiesFile(f: File, version: String): Unit =
- IO.write(f, "version.number = "+version+"\ncopyright.string = Copyright 2002-2011, LAMP/EPFL")
-
- def makeFullVersionString(baseDirectory: File, baseVersion: String, git: GitRunner, s: TaskStreams) = baseVersion+"."+getGitRevision(baseDirectory, git, currentDay, s)
-
- // TODO - do we want this in the build number?
- def currentDay = (new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss")) format (new java.util.Date)
-
-
-
- def getGitRevision(baseDirectory: File, git: GitRunner, date: String, s: TaskStreams) = {
-
- val mergeBase = {
- // TODO - Cache this value.
- // git("merge-base","v2.8.2","v2.9.1","master")(baseDirectory, s.log)
- "df13e31bbb"
- }
- // current commit sha
- val sha =
- git("rev-list", "-n", "1", "HEAD")(baseDirectory, s.log)
-
- val commits =
- git("--no-pager", "log", "--pretty=oneline", mergeBase +"..HEAD")(baseDirectory, s.log) split "[\r\n]+" size
-
- "rdev-%d-%s-g%s" format (commits, date, sha.substring(0,7))
- }
-
}
diff --git a/project/ShaResolve.scala b/project/ShaResolve.scala
index f54e96c0c6..e6824ee464 100644
--- a/project/ShaResolve.scala
+++ b/project/ShaResolve.scala
@@ -40,6 +40,8 @@ object ShaResolve {
throw t
}
+ // TODO - Finish this publishing aspect.
+
def getShaFromShafile(file: File): String = parseShaFile(file)._2
// This should calculate the SHA sum of a file the same as the linux process.
diff --git a/project/Versions.scala b/project/Versions.scala
new file mode 100644
index 0000000000..b588ec55ac
--- /dev/null
+++ b/project/Versions.scala
@@ -0,0 +1,142 @@
+import sbt._
+import Keys._
+import java.util.Properties
+import scala.util.control.Exception.catching
+import java.lang.{NumberFormatException => NFE}
+import java.io.FileInputStream
+import com.jsuereth.git.GitRunner
+import com.jsuereth.git.GitKeys.gitRunner
+
+case class VersionInfo(canonical: String,
+ maven: String,
+ osgi: String)
+
+/** this file is responsible for setting up Scala versioning schemes and updating all the necessary bits. */
+object Versions {
+ val buildNumberFile = SettingKey[File]("scala-build-number-file")
+ // TODO - Make this a setting?
+ val buildNumberProps = SettingKey[BaseBuildNumber]("scala-build-number-props")
+ val buildRelease = SettingKey[Boolean]("scala-build-release", "This is set to true if we're building a release.")
+ val mavenSuffix = SettingKey[String]("scala-maven-suffix", "This is set to whatever maven suffix is required.")
+
+ val gitSha = TaskKey[String]("scala-git-sha", "The sha of the current git commit.")
+ val gitDate = TaskKey[String]("scala-git-date", "The date of the current git commit.")
+
+ val mavenVersion = SettingKey[String]("scala-maven-version", "The maven version number.")
+ val osgiVersion = TaskKey[String]("scala-osgi-version", "The OSGi version number.")
+ val canonicalVersion = TaskKey[String]("scala-canonical-version", "The canonical version number.")
+
+ val scalaVersions = TaskKey[VersionInfo]("scala-version-info", "The scala versions used for this build.")
+
+
+
+ def settings: Seq[Setting[_]] = Seq(
+ buildNumberFile <<= baseDirectory apply (_ / "build.number"),
+ buildNumberProps <<= buildNumberFile apply loadBuildNumberProps,
+ buildRelease := Option(System.getProperty("build.release")) map (!_.isEmpty) getOrElse false,
+ mavenSuffix <<= buildRelease apply pickMavenSuffix,
+ mavenVersion <<= (buildNumberProps, mavenSuffix) apply makeMavenVersion,
+ gitSha <<= (gitRunner, baseDirectory, streams) map getGitSha,
+ gitDate <<= (gitRunner, baseDirectory, streams) map getGitDate,
+ osgiVersion <<= (buildNumberProps, gitDate, gitSha) map makeOsgiVersion,
+ canonicalVersion <<= (buildRelease, mavenVersion, buildNumberProps, gitDate, gitSha) map makeCanonicalVersion,
+ scalaVersions <<= (canonicalVersion, mavenVersion, osgiVersion) map VersionInfo.apply
+ )
+
+
+ /** This generates a properties file, if it does not already exist, with the maximum lastmodified timestamp
+ * of any source file. */
+ def generateVersionPropertiesFile(name: String)(dir: File, versions: VersionInfo, skip: Boolean, s: TaskStreams): Seq[File] = {
+ // TODO - We can probably clean this up by moving caching bits elsewhere perhaps....
+ val target = dir / name
+ // TODO - Regenerate on triggers, like recompilation or something...
+ def hasSameVersion: Boolean = {
+ val props = new java.util.Properties
+ val in = new java.io.FileInputStream(target)
+ try props.load(in) finally in.close()
+ versions.canonical == (props getProperty "version.number")
+ }
+ if (!target.exists || !(skip || hasSameVersion)) {
+ makeVersionPropertiesFile(target, versions)
+ }
+ target :: Nil
+ }
+
+ // This creates the *.properties file used to determine the current version of scala at runtime. TODO - move these somewhere utility like.
+ def makeVersionPropertiesFile(f: File, versions: VersionInfo): Unit =
+ IO.write(f, "version.number = "+versions.canonical+"\n"+
+ "osgi.number = "+versions.osgi+"\n"+
+ "maven.number = "+versions.maven+"\n"+
+ "copyright.string = Copyright 2002-2011, LAMP/EPFL")
+
+ def makeCanonicalVersion(isRelease: Boolean, mvnVersion: String, base: BaseBuildNumber, gitDate: String, gitSha: String): String =
+ if(isRelease) mvnVersion
+ else {
+ val suffix = if(base.bnum > 0) "-%d".format(base.bnum) else ""
+ "%s.%s.%s%s-%s-%s" format (base.major, base.minor, base.patch, suffix, gitDate, gitSha)
+ }
+
+ def makeMavenVersion(base: BaseBuildNumber, suffix: String): String = {
+ val firstSuffix = if(base.bnum > 0) "-%d".format(base.bnum) else ""
+ "%d.%d.%d%s%s" format (base.major, base.minor, base.patch, firstSuffix, suffix)
+ }
+
+ def makeOsgiVersion(base: BaseBuildNumber, gitDate: String, gitSha: String): String = {
+ val suffix = if(base.bnum > 0) "-%d".format(base.bnum) else ""
+ "%s.%s.%s.v%s%s-%s" format (base.major, base.minor, base.patch, gitDate, suffix, gitSha)
+ }
+
+ /** Determines what the maven sufffix should be for this build. */
+ def pickMavenSuffix(isRelease: Boolean): String = {
+ def default = if(isRelease) "" else "-SNAPSHOT"
+ Option(System.getProperty("maven.version.suffix")) getOrElse default
+ }
+
+ /** Loads the build.number properties file into SBT. */
+ def loadBuildNumberProps(file: File): BaseBuildNumber = {
+ val fin = new FileInputStream(file)
+ try {
+ val props = new Properties()
+ props.load(fin)
+ def getProp(name: String): Int =
+ (for {
+ v <- Option(props.getProperty(name))
+ v2 <- catching(classOf[NFE]) opt v.toInt
+ } yield v2) getOrElse sys.error("Could not convert %s to integer!" format (name))
+
+ BaseBuildNumber(
+ major=getProp("version.major"),
+ minor=getProp("version.minor"),
+ patch=getProp("version.patch"),
+ bnum =getProp("version.bnum")
+ )
+ } finally fin.close()
+ }
+
+
+ def getGitDate(git: GitRunner, baseDirectory: File, s: TaskStreams): String = {
+ val lines = getGitLines("log","-1","--format=\"%ci\"")(git,baseDirectory, s)
+ val line = if(lines.isEmpty) sys.error("Could not retreive git commit sha!") else lines.head
+ // Lines *always* start with " for some reason...
+ line drop 1 split "\\s+" match {
+ case Array(date, time, _*) => "%s-%s" format (date.replaceAll("\\-", ""), time.replaceAll(":",""))
+ case _ => sys.error("Could not parse git date: " + line)
+ }
+ }
+
+ def getGitSha(git: GitRunner, baseDirectory: File, s: TaskStreams): String = {
+ val lines = getGitLines("log","-1","--format=\"%H\"", "HEAD")(git,baseDirectory, s)
+ val line = if(lines.isEmpty) sys.error("Could not retreive git commit sha!") else lines.head
+ val noquote = if(line startsWith "\"") line drop 1 else line
+ val nog = if(noquote startsWith "g") noquote drop 1 else noquote
+ nog take 10
+ }
+
+ def getGitLines(args: String*)(git: GitRunner, baseDirectory: File, s: TaskStreams): Seq[String] =
+ git(args: _*)(baseDirectory, s.log) split "[\r\n]+"
+}
+
+
+case class BaseBuildNumber(major: Int, minor: Int, patch: Int, bnum: Int) {
+ override def toString = "BaseBuildNumber(%d.%d.%d-%d)" format (major, minor, patch, bnum)
+}
diff --git a/project/project/Build.scala b/project/project/Build.scala
index 1ceb7e2ef2..bd1250fc39 100644
--- a/project/project/Build.scala
+++ b/project/project/Build.scala
@@ -2,6 +2,6 @@ import sbt._
object PluginDef extends Build {
override def projects = Seq(root)
lazy val root = Project("plugins", file(".")) dependsOn(proguard, git)
- lazy val proguard = uri("git://github.com/jsuereth/xsbt-proguard-plugin.git")
+ lazy val proguard = uri("git://github.com/jsuereth/xsbt-proguard-plugin.git#sbt-0.11")
lazy val git = uri("git://github.com/sbt/sbt-git-plugin.git#scala-build")
}
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index edafde1346..0612dcdfd4 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -1207,7 +1207,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
def isPrimitiveValueClass(sym: Symbol) = ScalaValueClasses contains sym
def isNonUnitValueClass(sym: Symbol) = isPrimitiveValueClass(sym) && (sym != UnitClass)
def isSpecializableClass(sym: Symbol) = isPrimitiveValueClass(sym) || (sym == AnyRefClass)
- def isScalaValueType(tp: Type) = ScalaValueClasses contains tp.typeSymbol
+ def isPrimitiveValueType(tp: Type) = isPrimitiveValueClass(tp.typeSymbol)
/** Is symbol a boxed value class, e.g. java.lang.Integer? */
def isBoxedValueClass(sym: Symbol) = boxedValueClassesSet(sym)
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 2a5b759f94..724e5bf628 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -2088,7 +2088,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation of symbol's definition key word */
final def keyString: String =
if (isJavaInterface) "interface"
- else if (isTrait) "trait"
+ else if (isTrait && !isImplClass) "trait"
else if (isClass) "class"
else if (isType && !isParameter) "type"
else if (isVariable) "var"
@@ -2116,6 +2116,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isSetter) ("setter", if (isSourceMethod) "method" else "value", "SET")
else if (isTerm && isLazy) ("lazy value", "lazy value", "LAZ")
else if (isVariable) ("field", "variable", "VAR")
+ else if (isImplClass) ("implementation class", "class", "IMPL")
else if (isTrait) ("trait", "trait", "TRT")
else if (isClass) ("class", "class", "CLS")
else if (isType) ("type", "type", "TPE")
@@ -2232,7 +2233,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
def infosString = infos.toString
- def debugLocationString = fullLocationString + " " + debugFlagString
+ def debugLocationString = fullLocationString + " (flags: " + debugFlagString + ")"
private def defStringCompose(infoString: String) = compose(
flagString,
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index e2d9310424..3e7f23800c 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -145,11 +145,12 @@ trait Trees extends api.Trees { self: SymbolTable =>
*/
def summaryString: String = tree match {
case Literal(const) => "Literal(" + const + ")"
- case Select(qual, name) => qual.summaryString + "." + name.decode
+ case Ident(name) => "Ident(%s)".format(name.decode)
+ case Select(qual, name) => "Select(%s, %s)".format(qual.summaryString, name.decode)
case t: NameTree => t.name.longString
case t =>
t.shortClass + (
- if (t.symbol != null && t.symbol != NoSymbol) " " + t.symbol
+ if (t.symbol != null && t.symbol != NoSymbol) "(" + t.symbol + ")"
else ""
)
}
diff --git a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
index eb384f9a85..1424226042 100644
--- a/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
+++ b/src/compiler/scala/reflect/internal/util/TraceSymbolActivity.scala
@@ -7,7 +7,7 @@ trait TraceSymbolActivity {
val global: SymbolTable
import global._
- if (traceSymbolActivity)
+ if (traceSymbolActivity && !global.inReflexiveMirror)
scala.sys addShutdownHook showAllSymbols()
private type Set[T] = scala.collection.immutable.Set[T]
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index d3564017f9..de270a76f1 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -162,7 +162,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
/** Register new context; called for every created context
*/
- def registerContext(c: analyzer.Context) {}
+ def registerContext(c: analyzer.Context) {
+ lastSeenContext = c
+ }
/** Register top level class (called on entering the class)
*/
@@ -894,6 +896,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
curRun = null
}
+ object typeDeconstruct extends {
+ val global: Global.this.type = Global.this
+ } with interpreter.StructuredTypeStrings
+
/** There are common error conditions where when the exception hits
* here, currentRun.currentUnit is null. This robs us of the knowledge
* of what file was being compiled when it broke. Since I really
@@ -901,6 +907,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
*/
private var lastSeenSourceFile: SourceFile = NoSourceFile
+ /** Let's share a lot more about why we crash all over the place.
+ * People will be very grateful.
+ */
+ private var lastSeenContext: analyzer.Context = null
+
/** The currently active run
*/
def currentRun: Run = curRun
@@ -929,25 +940,64 @@ class Global(var currentSettings: Settings, var reporter: Reporter) extends Symb
@inline final def beforeTyper[T](op: => T): T = beforePhase(currentRun.typerPhase)(op)
@inline final def beforeUncurry[T](op: => T): T = beforePhase(currentRun.uncurryPhase)(op)
+ def explainContext(c: analyzer.Context): String = (
+ if (c == null) "" else (
+ """| context owners: %s
+ |
+ |Enclosing block or template:
+ |%s""".format(
+ c.owner.ownerChain.takeWhile(!_.isPackageClass).mkString(" -> "),
+ nodePrinters.nodeToString(c.enclClassOrMethod.tree)
+ )
+ )
+ )
+ // Owners up to and including the first package class.
+ private def ownerChainString(sym: Symbol): String = (
+ if (sym == null) ""
+ else sym.ownerChain.span(!_.isPackageClass) match {
+ case (xs, pkg :: _) => (xs :+ pkg) mkString " -> "
+ case _ => sym.ownerChain mkString " -> " // unlikely
+ }
+ )
+ private def formatExplain(pairs: (String, Any)*): String = (
+ pairs.toList collect { case (k, v) if v != null => "%20s: %s".format(k, v) } mkString "\n"
+ )
+
+ def explainTree(t: Tree): String = formatExplain(
+ )
+
/** Don't want to introduce new errors trying to report errors,
* so swallow exceptions.
*/
override def supplementErrorMessage(errorMessage: String): String = try {
- """|
- | while compiling: %s
- | current phase: %s
- | library version: %s
- | compiler version: %s
- | reconstructed args: %s
- |
- |%s""".stripMargin.format(
- currentSource.path,
- phase,
- scala.util.Properties.versionString,
- Properties.versionString,
- settings.recreateArgs.mkString(" "),
- if (opt.debug) "Current unit body:\n" + currentUnit.body + "\n" + errorMessage else errorMessage
+ val tree = analyzer.lastTreeToTyper
+ val sym = tree.symbol
+ val tpe = tree.tpe
+ val enclosing = lastSeenContext.enclClassOrMethod.tree
+
+ val info1 = formatExplain(
+ "while compiling" -> currentSource.path,
+ "during phase" -> phase,
+ "library version" -> scala.util.Properties.versionString,
+ "compiler version" -> Properties.versionString,
+ "reconstructed args" -> settings.recreateArgs.mkString(" ")
+ )
+ val info2 = formatExplain(
+ "last tree to typer" -> tree.summaryString,
+ "symbol" -> Option(sym).fold("null")(_.debugLocationString),
+ "symbol definition" -> Option(sym).fold("null")(_.defString),
+ "tpe" -> tpe,
+ "symbol owners" -> ownerChainString(sym),
+ "context owners" -> ownerChainString(lastSeenContext.owner)
)
+ val info3: List[String] = (
+ ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
+ ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
+ ++ ( if (!opt.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
+ ++ ( List(errorMessage) )
+ )
+
+ ("\n" + info1) :: info2 :: info3 mkString "\n\n"
}
catch { case x: Exception => errorMessage }
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index a93d9efded..23fcffd657 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -236,7 +236,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
mkMethodCall(
PredefModule,
wrapArrayMethodName(elemtp),
- if (isScalaValueType(elemtp)) Nil else List(elemtp),
+ if (isPrimitiveValueType(elemtp)) Nil else List(elemtp),
List(tree)
)
}
@@ -261,7 +261,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
* elem type elemtp to expected type pt.
*/
def mkCastArray(tree: Tree, elemtp: Type, pt: Type) =
- if (elemtp.typeSymbol == AnyClass && isScalaValueType(tree.tpe.typeArgs.head))
+ if (elemtp.typeSymbol == AnyClass && isPrimitiveValueType(tree.tpe.typeArgs.head))
mkCast(mkRuntimeCall(nme.toObjectArray, List(tree)), pt)
else
mkCast(tree, pt)
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 4aeb537f9b..f7541a4739 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -1208,7 +1208,7 @@ abstract class GenICode extends SubComponent {
if (!tree.symbol.isPackageClass) tree.symbol
else tree.symbol.info.member(nme.PACKAGE) match {
case NoSymbol => assert(false, "Cannot use package as value: " + tree) ; NoSymbol
- case s => Console.err.println("Bug: found package class where package object expected. Converting.") ; s.moduleClass
+ case s => debugwarn("Bug: found package class where package object expected. Converting.") ; s.moduleClass
}
)
debuglog("LOAD_MODULE from %s: %s".format(tree.shortClass, sym))
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
index 61f3670f5f..c3525037cd 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -179,7 +179,7 @@ trait ModelFactoryImplicitSupport {
hardcoded.arraySkipConversions.contains(conv.conversionQualifiedName))
// Filter out non-sensical conversions from value types
- if (isScalaValueType(sym.tpe))
+ if (isPrimitiveValueType(sym.tpe))
conversions = conversions.filter((ic: ImplicitConversion) =>
hardcoded.valueClassFilter(sym.nameString, ic.conversionQualifiedName))
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 9e7e4b3f4f..3625b19dd4 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -619,7 +619,7 @@ abstract class Erasure extends AddInterfaces
tree.duplicate setType pt
} else if (tree.tpe != null && tree.tpe.typeSymbol == ArrayClass && pt.typeSymbol == ArrayClass) {
// See SI-2386 for one example of when this might be necessary.
- val needsExtraCast = isScalaValueType(tree.tpe.typeArgs.head) && !isScalaValueType(pt.typeArgs.head)
+ val needsExtraCast = isPrimitiveValueType(tree.tpe.typeArgs.head) && !isPrimitiveValueType(pt.typeArgs.head)
val tree1 = if (needsExtraCast) gen.mkRuntimeCall(nme.toObjectArray, List(tree)) else tree
gen.mkAttributedCast(tree1, pt)
} else gen.mkAttributedCast(tree, pt)
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index aea29a27dd..7e780304e7 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -67,7 +67,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
import definitions.{
RootClass, BooleanClass, UnitClass, ArrayClass,
- ScalaValueClasses, isPrimitiveValueClass, isScalaValueType,
+ ScalaValueClasses, isPrimitiveValueClass, isPrimitiveValueType,
SpecializedClass, UnspecializedClass, AnyRefClass, ObjectClass, AnyRefModule,
GroupOfSpecializable, uncheckedVarianceClass, ScalaInlineClass
}
@@ -145,7 +145,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
def includes(t1: TypeEnv, t2: TypeEnv) = t1 forall {
case (sym, tpe) =>
t2 get sym exists { t2tp =>
- (tpe == t2tp) || !(isScalaValueType(tpe) || isScalaValueType(t2tp)) // u.t.b. (t2tp <:< AnyRefClass.tpe)
+ (tpe == t2tp) || !(isPrimitiveValueType(tpe) || isPrimitiveValueType(t2tp)) // u.t.b. (t2tp <:< AnyRefClass.tpe)
}
}
@@ -266,7 +266,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* specialized type.
*/
def survivingArgs(sym: Symbol, args: List[Type]): List[Type] =
- for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isScalaValueType(tpe))
+ for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isPrimitiveValueType(tpe))
yield tpe
val specializedType = new TypeMap {
@@ -448,7 +448,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Type parameters that survive when specializing in the specified environment. */
def survivingParams(params: List[Symbol], env: TypeEnv) =
- params.filter(p => !p.isSpecialized || !isScalaValueType(env(p)))
+ params.filter(p => !p.isSpecialized || !isPrimitiveValueType(env(p)))
/** Produces the symbols from type parameters `syms` of the original owner,
* in the given type environment `env`. The new owner is `nowner`.
@@ -1588,7 +1588,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// val (_, origtparams) = splitParams(source.typeParams)
val env = typeEnv(symbol)
val boundTvars = env.keySet
- val origtparams = source.typeParams.filter(tparam => !boundTvars(tparam) || !isScalaValueType(env(tparam)))
+ val origtparams = source.typeParams.filter(tparam => !boundTvars(tparam) || !isPrimitiveValueType(env(tparam)))
if (origtparams.nonEmpty || symbol.typeParams.nonEmpty)
debuglog("substituting " + origtparams + " for " + symbol.typeParams)
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 484c8beb1b..6faa9a3cb7 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -254,6 +254,12 @@ trait SyntheticMethods extends ast.TreeDSL {
Block(valdef :: mixes, finish)
}
}
+ def chooseHashcode = {
+ if (accessors exists (x => isPrimitiveValueType(x.tpe.finalResultType)))
+ specializedHashcode
+ else
+ forwardToRuntime(Object_hashCode)
+ }
def valueClassMethods = List(
Any_hashCode -> (() => hashCodeDerivedValueClassMethod),
@@ -261,7 +267,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def caseClassMethods = productMethods ++ productNMethods ++ Seq(
- Object_hashCode -> (() => specializedHashcode),
+ Object_hashCode -> (() => chooseHashcode),
Object_toString -> (() => forwardToRuntime(Object_toString)),
Object_equals -> (() => equalsCaseClassMethod)
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 343636ff1e..34e1aaedfd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -31,7 +31,6 @@ trait Typers extends Modes with Adaptations with Taggings {
import global._
import definitions._
-
import patmat.DefaultOverrideMatchAttachment
final def forArgMode(fun: Tree, mode: Int) =
@@ -85,6 +84,12 @@ trait Typers extends Modes with Adaptations with Taggings {
private def isPastTyper = phase.id > currentRun.typerPhase.id
+ // To enable decent error messages when the typer crashes.
+ // TODO - this only catches trees which go through def typed,
+ // but there are all kinds of back ways - typedClassDef, etc. etc.
+ // Funnel everything through one doorway.
+ var lastTreeToTyper: Tree = EmptyTree
+
// when true:
// - we may virtualize matches (if -Xexperimental and there's a suitable __match in scope)
// - we synthesize PartialFunction implementations for `x => x match {...}` and `match {...}` when the expected type is PartialFunction
@@ -4972,6 +4977,7 @@ trait Typers extends Modes with Adaptations with Taggings {
* @return ...
*/
def typed(tree: Tree, mode: Int, pt: Type): Tree = {
+ lastTreeToTyper = tree
indentTyping()
var alreadyTyped = false
diff --git a/src/partest/scala/tools/partest/nest/SBTRunner.scala b/src/partest/scala/tools/partest/nest/SBTRunner.scala
index 750e270c18..5d994eeb37 100644
--- a/src/partest/scala/tools/partest/nest/SBTRunner.scala
+++ b/src/partest/scala/tools/partest/nest/SBTRunner.scala
@@ -54,15 +54,17 @@ object SBTRunner extends DirectRunner {
val config = parseArgs(args, CommandLineOptions())
fileManager.SCALAC_OPTS = config.scalacOptions
fileManager.CLASSPATH = config.classpath getOrElse sys.error("No classpath set")
+
+ def findClasspath(jar: String, name: String): Option[String] = {
+ val optJar = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches (".*"+jar+".*\\.jar"))).headOption
+ val optClassDir = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches (".*"+name+File.separator+"classes"))).headOption
+ optJar orElse optClassDir
+ }
// Find scala library jar file...
- val lib: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-library.*\\.jar")).headOption
- fileManager.LATEST_LIB = lib getOrElse sys.error("No scala-library found! Classpath = " + fileManager.CLASSPATH)
- val comp: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-compiler.*\\.jar")).headOption
- fileManager.LATEST_COMP = comp getOrElse sys.error("No scala-compiler found! Classpath = " + fileManager.CLASSPATH)
- val partest: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-partest.*\\.jar")).headOption
- fileManager.LATEST_PARTEST = partest getOrElse sys.error("No scala-partest found! Classpath = " + fileManager.CLASSPATH)
- val actors: Option[String] = (fileManager.CLASSPATH split File.pathSeparator filter (_ matches ".*scala-actors.*\\.jar")).headOption
- fileManager.LATEST_ACTORS = actors getOrElse sys.error("No scala-actors found! Classpath = " + fileManager.CLASSPATH)
+ fileManager.LATEST_LIB = findClasspath("scala-library", "scala-library") getOrElse sys.error("No scala-library found! Classpath = " + fileManager.CLASSPATH)
+ fileManager.LATEST_COMP = findClasspath("scala-compiler", "scala-compiler") getOrElse sys.error("No scala-compiler found! Classpath = " + fileManager.CLASSPATH)
+ fileManager.LATEST_PARTEST = findClasspath("scala-partest", "partest") getOrElse sys.error("No scala-partest found! Classpath = " + fileManager.CLASSPATH)
+ fileManager.LATEST_ACTORS = findClasspath("scala-actors", "actors") getOrElse sys.error("No scala-actors found! Classpath = " + fileManager.CLASSPATH)
// TODO - Do something useful here!!!
fileManager.JAVAC_CMD = "javac"
diff --git a/test/files/pos/t4651.scala b/test/files/pos/t4651.scala
new file mode 100644
index 0000000000..0612a8fcfb
--- /dev/null
+++ b/test/files/pos/t4651.scala
@@ -0,0 +1,12 @@
+object Test {
+ def analyze(x: Any) = x match {
+ case s: String => println("It's a string: " + s)
+ case 1 => println("It's a one")
+ case (a: Int, b) => println("It's a pair of and int " + a +
+ " and something " + b)
+ case 1 :: 2 :: _ => println("It's a list starting with 1, 2")
+ case List(a, b, c) => println("It's a three-element list with " +
+ a + ", " + b + ", " + c)
+ case _ => println("It's something different")
+ }
+}
diff --git a/test/files/run/t3702.check b/test/files/run/t3702.check
new file mode 100644
index 0000000000..31c2ac4ed1
--- /dev/null
+++ b/test/files/run/t3702.check
@@ -0,0 +1,2 @@
+()
+6
diff --git a/test/files/run/t3702.scala b/test/files/run/t3702.scala
new file mode 100644
index 0000000000..021abcb625
--- /dev/null
+++ b/test/files/run/t3702.scala
@@ -0,0 +1,11 @@
+object Test {
+ def foo(h: Any, t: List[Any]) = h match {
+ case 5 :: _ => ()
+ case List(from) => from
+ }
+
+ def main(args: Array[String]): Unit = {
+ println(foo(5 :: Nil, List(1,2,3)))
+ println(foo(6 :: Nil, List(1,2,3)))
+ }
+}
diff --git a/test/files/run/t4482.check b/test/files/run/t4482.check
new file mode 100644
index 0000000000..0cfbf08886
--- /dev/null
+++ b/test/files/run/t4482.check
@@ -0,0 +1 @@
+2
diff --git a/test/files/run/t4482.scala b/test/files/run/t4482.scala
new file mode 100644
index 0000000000..392861c22e
--- /dev/null
+++ b/test/files/run/t4482.scala
@@ -0,0 +1,15 @@
+trait Foo { def i: Int }
+trait Bar
+
+case class Spam(i: Int) extends Foo with Bar
+
+object Test {
+ def matchParent(p:Any) = p match {
+ case f:Foo if f.i == 1 => 1
+ case _:Bar => 2
+ case _:Foo => 3
+ }
+ def main(args: Array[String]): Unit = {
+ println(matchParent(Spam(3)))
+ }
+}
diff --git a/test/pending/pos/t1832.scala b/test/pending/pos/t1832.scala
new file mode 100644
index 0000000000..bca863f4bd
--- /dev/null
+++ b/test/pending/pos/t1832.scala
@@ -0,0 +1,10 @@
+// Edit by paulp: reduced.
+trait Cloning {
+ trait Foo
+ def fn(g: Int => Unit): Foo
+
+ implicit def mkStar(i: Int) = new { def *(a: Foo): Foo = null }
+
+ val pool1 = 4 * fn { case i => i * 2 }
+ val pool2 = 4 * fn { case i: Int => i * 2 }
+}
diff --git a/test/pending/pos/t3439.scala b/test/pending/pos/t3439.scala
new file mode 100644
index 0000000000..425f1aeeb5
--- /dev/null
+++ b/test/pending/pos/t3439.scala
@@ -0,0 +1,2 @@
+abstract class ParametricMessage[M: Manifest](msg: M) { def message = msg }
+case class ParametricMessage1[M: Manifest](msg: M, p1: Class[_]) extends ParametricMessage(msg)
diff --git a/test/pending/pos/t4717.scala b/test/pending/pos/t4717.scala
index 43cf412bc6..7eaa3dd487 100644
--- a/test/pending/pos/t4717.scala
+++ b/test/pending/pos/t4717.scala
@@ -1,7 +1,7 @@
-trait Bug1[@specialized +A] extends TraversableOnce[A] {
- def ++[B >: A](that: TraversableOnce[B]): Iterator[B] = new Iterator[B] {
- lazy val it = that.toIterator
- def hasNext = it.hasNext
- def next = it.next
+trait Bounds[@specialized A] {
+ // okay without `>: A`
+ def x[B >: A]: Unit = new Bounds[B] {
+ lazy val it = ??? // def or val okay
+ it
}
} \ No newline at end of file
diff --git a/test/pending/pos/t5091.scala b/test/pending/pos/t5091.scala
new file mode 100644
index 0000000000..217e83f66d
--- /dev/null
+++ b/test/pending/pos/t5091.scala
@@ -0,0 +1,11 @@
+object RecursiveValueNeedsType {
+
+ def foo(param: String) = 42
+ def bar(n: Int) = 42
+
+ {
+ val xxx = foo(param = null)
+ val param = bar(xxx)
+ }
+
+}
diff --git a/test/pending/pos/t5231.scala b/test/pending/pos/t5231.scala
new file mode 100644
index 0000000000..77e6631ebb
--- /dev/null
+++ b/test/pending/pos/t5231.scala
@@ -0,0 +1,18 @@
+object Client {
+ sealed trait ConfigLike {
+ def clientID: Int
+ }
+
+ object Config {
+ def apply() : ConfigBuilder = new ConfigBuilder()
+ implicit def build( cb: ConfigBuilder ) : Config = cb.build
+ }
+
+ final class Config private[Client]( val clientID: Int )
+ extends ConfigLike
+
+ final class ConfigBuilder private () extends ConfigLike {
+ var clientID: Int = 0
+ def build : Config = new Config( clientID )
+ }
+}
diff --git a/test/pending/pos/t5265.scala b/test/pending/pos/t5265.scala
new file mode 100644
index 0000000000..3be7d2187e
--- /dev/null
+++ b/test/pending/pos/t5265.scala
@@ -0,0 +1,21 @@
+import java.util.Date
+
+trait TDate
+
+trait TT[A1,T1]
+
+trait TTFactory[F,G] {
+ def create(f: F) : TT[F,G]
+ def sample: F
+}
+
+object Impls {
+
+ // If the c1 is declared before c2, it compiles fine
+ implicit def c2(s: Date) = c1.create(s)
+
+ implicit val c1 = new TTFactory[Date,TDate] {
+ def create(v: Date): TT[Date,TDate] = sys.error("")
+ def sample = new Date
+ }
+} \ No newline at end of file