diff options
author | Martin Odersky <odersky@gmail.com> | 2016-12-14 17:38:21 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-12-14 18:25:19 +0100 |
commit | 90ce8875c874f011b335390b3b41422793e1c7aa (patch) | |
tree | fae5c3e54ab92b8651122931035ddfd35f61e532 | |
parent | ba06bf06721f1a8de7d68d22ad7eba27fff90c43 (diff) | |
download | dotty-90ce8875c874f011b335390b3b41422793e1c7aa.tar.gz dotty-90ce8875c874f011b335390b3b41422793e1c7aa.tar.bz2 dotty-90ce8875c874f011b335390b3b41422793e1c7aa.zip |
More tests and other odds and end
- Add tests that work to pos/neg, tests that don't work yet to pending/pos/neg.
- Also, change .gitignore to allow for a local directory.
- Also add a draft page to the docs.
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | docs/dotc-internals/core-data-structures.md | 113 | ||||
-rw-r--r-- | tests/neg/t3683-modified.scala | 20 | ||||
-rw-r--r-- | tests/pending/pos/i1535.scala | 9 | ||||
-rw-r--r-- | tests/pending/pos/i1710.scala | 11 | ||||
-rw-r--r-- | tests/pending/run/i1732.scala | 8 | ||||
-rw-r--r-- | tests/pos/Monoid.scala | 61 | ||||
-rw-r--r-- | tests/pos/i1704.scala | 4 | ||||
-rw-r--r-- | tests/pos/i1777.scala | 9 |
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) + } +} |