aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--docs/dotc-internals/core-data-structures.md113
-rw-r--r--tests/neg/t3683-modified.scala20
-rw-r--r--tests/pending/pos/i1535.scala9
-rw-r--r--tests/pending/pos/i1710.scala11
-rw-r--r--tests/pending/run/i1732.scala8
-rw-r--r--tests/pos/Monoid.scala61
-rw-r--r--tests/pos/i1704.scala4
-rw-r--r--tests/pos/i1777.scala9
9 files changed, 239 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 9d9f8fa3b..1a0b1b6a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,7 @@ build/
.packages
/.cache-main
/.cache-tests
+
+# Put local stuff here
+local/
+
diff --git a/docs/dotc-internals/core-data-structures.md b/docs/dotc-internals/core-data-structures.md
new file mode 100644
index 000000000..eddc3398c
--- /dev/null
+++ b/docs/dotc-internals/core-data-structures.md
@@ -0,0 +1,113 @@
+(The following is work in progress)
+
+## Symbols and SymDenotations
+
+ - why symbols are not enough: their contents change all the time
+ - they change themselvesSo a `Symbol
+
+ - reference: string + sig
+
+
+Dotc is different from most other compilers in that it is centered around the idea of
+maintaining views of various artifacts associated with code. These views are indexed
+by tne
+
+A symbol refers to a definition in a source program. Traditionally,
+ compilers store context-dependent data in a _symbol table_. The
+ symbol then is the central reference to address context-dependent
+ data. But for `dotc`'s requirements it turns out that symbols are
+ both too little and too much for this task.
+
+Too little: The attributes of a symbol depend on the phase. Examples:
+Types are gradually simplified by several phases. Owners are changed
+in phases `LambdaLift` (when methods are lifted out to an enclosing
+class) and Flatten (when all classes are moved to top level). Names
+are changed when private members need to be accessed from outside
+their class (for instance from a nested class or a class implementing
+a trait). So a functional compiler, a `Symbol` by itself met mean
+much. Instead we are more interested in the attributes of a symbol at
+a given phase.
+
+`dotc` has a concept for "attributes of a symbol at
+
+Too much: If a symbol is used to refer to a definition in another
+compilation unit, we get problems for incremental recompilation. The
+unit containing the symbol might be changed and recompiled, which
+might mean that the definition referred to by the symbol is deleted or
+changed. This leads to the problem of stale symbols that refer to
+definitions that no longer exist in this form. `scalac` tried to
+address this problem by _rebinding_ symbols appearing in certain cross
+module references, but it turned out to be too difficult to do this
+reliably for all kinds of references. `dotc` attacks the problem at
+the root instead. The fundamental problem is that symbols are too
+specific to serve as a cross-module reference in a system with
+incremental compilation. They refer to a particular definition, but
+that definition may not persist unchanged after an edit.
+
+`dotc` uses instead a different approach: A cross module reference is
+always type, either a `TermRef` or ` TypeRef`. A reference type contains
+a prefix type and a name. The definition the type refers to is established
+dynamically based on these fields.
+
+
+a system where sources can be recompiled at any instance,
+
+ the concept of a `Denotation`.
+
+ Since definitions are transformed by phases,
+
+
+The [Dotty project](https://github.com/lampepfl/dotty)
+is a platform to develop new technology for Scala
+tooling and to try out concepts of future Scala language versions.
+Its compiler is a new design intended to reflect the
+lessons we learned from work with the Scala compiler. A clean redesign
+today will let us iterate faster with new ideas in the future.
+
+Today we reached an important milestone: The Dotty compiler can
+compile itself, and the compiled compiler can act as a drop-in for the
+original one. This is what one calls a *bootstrap*.
+
+## Why is this important?
+
+The main reason is that this gives us a some validation of the
+*trustworthiness* of the compiler itself. Compilers are complex beasts,
+and many things can go wrong. By far the worst things that can go
+wrong are bugs where incorrect code is produced. It's not fun debugging code that looks perfectly
+fine, yet gets translated to something subtly wrong by the compiler.
+
+Having the compiler compile itself is a good test to demonstrate that
+the generated code has reached a certain level of quality. Not only is
+a compiler a large program (44k lines in the case of dotty), it is
+also one that exercises a large part of the language in quite
+intricate ways. Moreover, bugs in the code of a compiler don't tend to
+go unnoticed, precisely because every part of a compiler feeds into
+other parts and all together are necessary to produce a correct
+translation.
+
+## Are We Done Yet?
+
+Far from it! The compiler is still very rough. A lot more work is
+needed to
+
+ - make it more robust, in particular when analyzing incorrect programs,
+ - improve error messages and warnings,
+ - improve the efficiency of some of the generated code,
+ - embed it in external tools such as sbt, REPL, IDEs,
+ - remove restrictions on what Scala code can be compiled,
+ - help in migrating Scala code that will have to be changed.
+
+## What Are the Next Steps?
+
+Over the coming weeks and months, we plan to work on the following topics:
+
+ - Make snapshot releases.
+ - Get the Scala standard library to compile.
+ - Work on SBT integration of the compiler.
+ - Work on IDE support.
+ - Investigate the best way to obtaining a REPL.
+ - Work on the build infrastructure.
+
+If you want to get your hands dirty with any of this, now is a good moment to get involved!
+To get started: <https://github.com/lampepfl/dotty>.
+
diff --git a/tests/neg/t3683-modified.scala b/tests/neg/t3683-modified.scala
new file mode 100644
index 000000000..19b981e0a
--- /dev/null
+++ b/tests/neg/t3683-modified.scala
@@ -0,0 +1,20 @@
+sealed trait Foo
+sealed trait Bar extends Foo
+sealed trait W[T >: Bar <: Foo]
+case class X() extends W[Foo]
+case class XX() extends W[Bar]
+case class Y() extends W[Bar]
+case class Z[T >: T <: Foo]( // error: cyclic reference
+ z1: W[T]
+) extends W[T]
+
+object Main {
+ // should warn for not including XX()
+ def f1(w: W[Bar]): Int = {
+ w match {
+ // case XX() => 2
+ case Y() => 1
+ case Z(z) => f1(z)
+ }
+ }
+}
diff --git a/tests/pending/pos/i1535.scala b/tests/pending/pos/i1535.scala
new file mode 100644
index 000000000..a574ca706
--- /dev/null
+++ b/tests/pending/pos/i1535.scala
@@ -0,0 +1,9 @@
+object Example {
+ case class C[H, T](h: H, t: T)
+
+ type I = Int
+
+ val p
+ : C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,C[I,I]]]]]]]]]]]]]]]]]]]]]]]
+ = C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,C(1,1)))))))))))))))))))))))
+}
diff --git a/tests/pending/pos/i1710.scala b/tests/pending/pos/i1710.scala
new file mode 100644
index 000000000..703244ea9
--- /dev/null
+++ b/tests/pending/pos/i1710.scala
@@ -0,0 +1,11 @@
+object Hello extends App {
+
+ val (a: Int, b: Int) = (4, 5) // works
+ val (z, k): (4, 5) = (4, 5) // works
+
+ val cd: (4, 5) = (4, 5)
+ val c: 4 = cd._1
+ val d: 5 = cd._2
+ val (x: 4, y: 5) = (4, 5) // doesn't work
+
+}
diff --git a/tests/pending/run/i1732.scala b/tests/pending/run/i1732.scala
new file mode 100644
index 000000000..748c9c3e5
--- /dev/null
+++ b/tests/pending/run/i1732.scala
@@ -0,0 +1,8 @@
+object Test {
+ import scala.util.control.Breaks
+ def main(args: Array[String]): Unit = {
+ Breaks.breakable {
+ Breaks.break
+ }
+ }
+}
diff --git a/tests/pos/Monoid.scala b/tests/pos/Monoid.scala
new file mode 100644
index 000000000..f6004cdf3
--- /dev/null
+++ b/tests/pos/Monoid.scala
@@ -0,0 +1,61 @@
+package strawman.typeclasses
+
+trait SemiGroup[T] {
+ def append(x: T, y: T): T
+}
+object SemiGroup {
+ class Ops {
+ implicit class InfixAppend[T: SemiGroup](self: T) {
+ def |+| (other: T): T = implicitly[SemiGroup[T]].append(self, other)
+ }
+ }
+ object ops extends Ops
+}
+
+trait Monoid[T] extends SemiGroup[T] {
+ val id: T
+}
+object Monoid {
+ object ops extends SemiGroup.Ops
+}
+
+trait Ring[T] extends Monoid[T] {
+ val zero = id
+ val one: T
+ def product(x: T, y: T): T
+}
+object Ring {
+ class Ops extends SemiGroup.Ops {
+ implicit class InfixProduct[T: Ring](self: T) {
+ def |*| (other: T): T = implicitly[Ring[T]].product(self, other)
+ }
+ }
+ object ops extends Ops
+}
+
+
+
+object Test {
+ implicit object StringMonoid extends Monoid[String] {
+ def append(x: String, y: String): String = x ++ y
+ val id = ""
+ }
+
+ implicit object IntRing extends Ring[Int] {
+ def append(x: Int, y: Int) = x + y
+ val id = 0
+ val one = 1
+ def product(x: Int, y: Int) = x * y
+ }
+
+ import Monoid.ops._ // works in dotty, fails in scalac
+ import Ring.ops._
+ "abc" |+| "def"
+ "abc" |+| StringMonoid.id
+ StringMonoid.id |+| "abc"
+
+ 1 |+| 2
+ 3 |*| 3
+
+
+}
diff --git a/tests/pos/i1704.scala b/tests/pos/i1704.scala
new file mode 100644
index 000000000..94bc03c4d
--- /dev/null
+++ b/tests/pos/i1704.scala
@@ -0,0 +1,4 @@
+trait AnyRef {
+ val StringMatch = new AnyRef {}
+ trait Something { (AnyRef) match { case (StringMatch) => } }
+}
diff --git a/tests/pos/i1777.scala b/tests/pos/i1777.scala
new file mode 100644
index 000000000..381ff9139
--- /dev/null
+++ b/tests/pos/i1777.scala
@@ -0,0 +1,9 @@
+object Main extends App {
+ import scala.collection.immutable._
+ case class Foo(s: String)
+ {
+ implicit val orderingS: Ordering[String] = Ordering[String] // Crash
+ val tree = TreeMap.empty ++ (1 to 100).map { i => Foo(i.toString) -> i }
+ println(tree.getClass)
+ }
+}