Skip to content

Commit 4da0e51

Browse files
authored
Merge branch 'master' into add-tests2
2 parents c2ee6b1 + ba01fba commit 4da0e51

File tree

23 files changed

+182
-60
lines changed

23 files changed

+182
-60
lines changed

compiler/src/dotty/tools/dotc/core/PhantomErasure.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package dotty.tools.dotc.core
22

33
import dotty.tools.dotc.ast.tpd._
44
import dotty.tools.dotc.core.Contexts.Context
5-
import dotty.tools.dotc.core.Symbols.defn
5+
import dotty.tools.dotc.core.Symbols._
66
import dotty.tools.dotc.core.Types.Type
77

88
/** Phantom erasure erases:
@@ -27,4 +27,7 @@ object PhantomErasure {
2727
/** Returns the default erased tree for a phantom parameter ref */
2828
def erasedParameterRef(implicit ctx: Context): Tree = ref(defn.ErasedPhantom_UNIT)
2929

30+
/** Is it a pure term inserted by the phantom erasure? */
31+
def isErasedPhantom(sym: Symbol)(implicit ctx: Context): Boolean = sym eq defn.ErasedPhantom_UNIT
32+
3033
}

compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ public enum ErrorMessageID {
9797
DuplicatePrivateProtectedQualifierID,
9898
ExpectedStartOfTopLevelDefinitionID,
9999
MissingReturnTypeWithReturnStatementID,
100+
NoReturnFromInlineID,
101+
ReturnOutsideMethodDefinitionID,
100102
;
101103

102104
public int errorNumber() {

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,4 +1737,25 @@ object messages {
17371737
hl"you have to provide either ${"class"}, ${"trait"}, ${"object"}, or ${"enum"} definitions after qualifiers"
17381738
}
17391739

1740+
case class NoReturnFromInline(owner: Symbol)(implicit ctx: Context)
1741+
extends Message(NoReturnFromInlineID) {
1742+
val kind = "Syntax"
1743+
val msg = hl"no explicit ${"return"} allowed from inline $owner"
1744+
val explanation =
1745+
hl"""Methods marked with ${"@inline"} may not use ${"return"} statements.
1746+
|Instead, you should rely on the last expression's value being
1747+
|returned from a method.
1748+
|"""
1749+
}
1750+
1751+
case class ReturnOutsideMethodDefinition(owner: Symbol)(implicit ctx: Context)
1752+
extends Message(ReturnOutsideMethodDefinitionID) {
1753+
val kind = "Syntax"
1754+
val msg = hl"${"return"} outside method definition"
1755+
val explanation =
1756+
hl"""You used ${"return"} in ${owner}.
1757+
|${"return"} is a keyword and may only be used within method declarations.
1758+
|"""
1759+
}
1760+
17401761
}

compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,19 @@ class SyntheticMethods(thisTransformer: DenotTransformer) {
4141

4242
private var myValueSymbols: List[Symbol] = Nil
4343
private var myCaseSymbols: List[Symbol] = Nil
44+
private var myCaseModuleSymbols: List[Symbol] = Nil
4445

4546
private def initSymbols(implicit ctx: Context) =
4647
if (myValueSymbols.isEmpty) {
4748
myValueSymbols = List(defn.Any_hashCode, defn.Any_equals)
4849
myCaseSymbols = myValueSymbols ++ List(defn.Any_toString, defn.Product_canEqual,
4950
defn.Product_productArity, defn.Product_productPrefix, defn.Product_productElement)
51+
myCaseModuleSymbols = myCaseSymbols.filter(_ ne defn.Any_equals)
5052
}
5153

5254
def valueSymbols(implicit ctx: Context) = { initSymbols; myValueSymbols }
5355
def caseSymbols(implicit ctx: Context) = { initSymbols; myCaseSymbols }
56+
def caseModuleSymbols(implicit ctx: Context) = { initSymbols; myCaseModuleSymbols }
5457

5558
/** The synthetic methods of the case or value class `clazz`. */
5659
def syntheticMethods(clazz: ClassSymbol)(implicit ctx: Context): List[Tree] = {
@@ -60,7 +63,10 @@ class SyntheticMethods(thisTransformer: DenotTransformer) {
6063
else clazz.caseAccessors
6164

6265
val symbolsToSynthesize: List[Symbol] =
63-
if (clazz.is(Case)) caseSymbols
66+
if (clazz.is(Case)) {
67+
if (clazz.is(Module)) caseModuleSymbols
68+
else caseSymbols
69+
}
6470
else if (isDerivedValueClass(clazz)) valueSymbols
6571
else Nil
6672

compiler/src/dotty/tools/dotc/transform/localopt/Simplify.scala

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import core.NameOps._
1111
import transform.TreeTransforms.{MiniPhaseTransform, TransformerInfo}
1212
import config.Printers.simplify
1313
import ast.tpd
14+
import dotty.tools.dotc.core.PhantomErasure
15+
16+
import scala.annotation.tailrec
1417

1518
/** This phase consists of a series of small, simple, local optimisations
1619
* applied as a fix point transformation over Dotty Trees.
@@ -60,6 +63,7 @@ class Simplify extends MiniPhaseTransform with IdentityDenotTransformer {
6063
new Devalify ::
6164
new Jumpjump ::
6265
new DropGoodCasts ::
66+
new DropNoEffects(this) ::
6367
new ConstantFold(this) ::
6468
Nil
6569

@@ -160,21 +164,28 @@ object Simplify {
160164
* System members are the only static final fields that are mutable.
161165
* See https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.5.4
162166
*/
163-
def isEffectivelyMutable(t: Tree)(implicit ctx: Context): Boolean = t match {
167+
@tailrec def isEffectivelyMutable(t: Tree)(implicit ctx: Context): Boolean = t match {
164168
case _ if t.symbol.is(Mutable) => true
165169
case s: Select => s.symbol.owner == defn.SystemModule
166-
case i: Ident => desugarIdent(i).exists(isEffectivelyMutable)
170+
case i: Ident =>
171+
desugarIdent(i) match {
172+
case Some(ident) => isEffectivelyMutable(ident)
173+
case None => false
174+
}
167175
case _ => false
168176
}
169177

170178
def isImmutableAccessor(t: Tree)(implicit ctx: Context): Boolean = {
171-
val isImmutableGetter = t.symbol.isGetter && !t.symbol.is(Mutable | Lazy)
172-
val isCaseAccessor = t.symbol.is(CaseAccessor) && !t.symbol.is(Mutable | Lazy)
173-
val isProductAccessor = t.symbol.exists &&
174-
t.symbol.owner.derivesFrom(defn.ProductClass) &&
175-
t.symbol.owner.is(CaseClass) &&
176-
t.symbol.name.isSelectorName &&
177-
!t.symbol.info.decls.exists(_.is(Mutable | Lazy)) // Conservatively covers case class A(var x: Int)
178-
isImmutableGetter || isCaseAccessor || isProductAccessor
179+
val sym = t.symbol
180+
val isImmutableGetter = sym.isGetter && !sym.is(Mutable | Lazy)
181+
val isCaseAccessor = sym.is(CaseAccessor) && !sym.is(Mutable | Lazy)
182+
val isProductAccessor = sym.exists &&
183+
sym.owner.derivesFrom(defn.ProductClass) &&
184+
sym.owner.is(CaseClass) &&
185+
sym.name.isSelectorName &&
186+
!sym.info.decls.exists(_.is(Mutable | Lazy)) // Conservatively covers case class A(var x: Int)
187+
val isErasedPhantom = PhantomErasure.isErasedPhantom(sym)
188+
189+
isImmutableGetter || isCaseAccessor || isProductAccessor || isErasedPhantom
179190
}
180191
}

compiler/src/dotty/tools/dotc/typer/Inliner.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import Contexts.Context
1616
import Names.{Name, TermName, EmptyTermName}
1717
import NameOps._
1818
import NameKinds.InlineAccessorName
19+
import ProtoTypes.selectionProto
1920
import SymDenotations.SymDenotation
2021
import Annotations._
2122
import transform.ExplicitOuter
@@ -524,7 +525,9 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
524525
}
525526

526527
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
527-
val res = super.typedSelect(tree, pt)
528+
assert(tree.hasType, tree)
529+
val qual1 = typed(tree.qualifier, selectionProto(tree.name, pt, this))
530+
val res = untpd.cpy.Select(tree)(qual1, tree.name).withType(tree.typeOpt)
528531
ensureAccessible(res.tpe, tree.qualifier.isInstanceOf[untpd.Super], tree.pos)
529532
res
530533
}

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -979,13 +979,13 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
979979
}
980980
def enclMethInfo(cx: Context): (Tree, Type) = {
981981
val owner = cx.owner
982-
if (cx == NoContext || owner.isType) {
983-
ctx.error("return outside method definition", tree.pos)
982+
if (owner.isType) {
983+
ctx.error(ReturnOutsideMethodDefinition(owner), tree.pos)
984984
(EmptyTree, WildcardType)
985985
}
986986
else if (owner != cx.outer.owner && owner.isRealMethod) {
987987
if (owner.isInlineMethod)
988-
(EmptyTree, errorType(em"no explicit return allowed from inline $owner", tree.pos))
988+
(EmptyTree, errorType(NoReturnFromInline(owner), tree.pos))
989989
else if (!owner.isCompleted)
990990
(EmptyTree, errorType(MissingReturnTypeWithReturnStatement(owner), tree.pos))
991991
else {

compiler/test/dotc/comptest.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ object comptest extends ParallelTesting {
1212
def isInteractive = true
1313
def testFilter = None
1414

15-
implicit val defaultOutputDir: String = "."
16-
1715
val posDir = "./tests/pos/"
1816
val negDir = "./tests/neg/"
1917
val dotcDir = "./src/dotty/"
@@ -26,6 +24,7 @@ object comptest extends ParallelTesting {
2624
dotcDir + "tools/dotc/core/Types.scala",
2725
dotcDir + "tools/dotc/ast/Trees.scala"
2826
),
29-
TestFlags("", Array("-Ylog:frontend", "-Xprompt"))
27+
TestFlags("", Array("-Ylog:frontend", "-Xprompt")),
28+
outDirectory = "."
3029
)
3130
}

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import dotty.tools.io.JFile
1515

1616

1717
class CompilationTests extends ParallelTesting {
18+
import ParallelTesting._
1819
import TestConfiguration._
1920
import CompilationTests._
2021

@@ -68,7 +69,6 @@ class CompilationTests extends ParallelTesting {
6869
compileFilesInDir("../tests/pos-special/strawman-collections", defaultOptions) +
6970
compileFile("../scala2-library/src/library/scala/collection/immutable/IndexedSeq.scala", defaultOptions) +
7071
compileFile("../scala2-library/src/library/scala/collection/parallel/mutable/ParSetLike.scala", defaultOptions) +
71-
compileFile("../tests/pos/t2171.scala", defaultOptimised) +
7272
compileList(
7373
"parSetSubset",
7474
List(
@@ -159,6 +159,7 @@ class CompilationTests extends ParallelTesting {
159159

160160
@Test def compileNeg: Unit = {
161161
compileShallowFilesInDir("../tests/neg", defaultOptions) +
162+
compileShallowFilesInDir("../tests/neg/no-optimise", defaultOptions) +
162163
compileFile("../tests/neg/customArgs/typers.scala", allowDoubleBindings) +
163164
compileFile("../tests/neg/customArgs/overrideClass.scala", scala2Mode) +
164165
compileFile("../tests/neg/customArgs/autoTuplingTest.scala", defaultOptions.and("-language:noAutoTupling")) +
@@ -186,12 +187,7 @@ class CompilationTests extends ParallelTesting {
186187

187188
@Test def runAll: Unit = {
188189
compileFilesInDir("../tests/run", defaultOptions) +
189-
compileFile("../tests/run/i3018.scala", defaultOptimised) +
190-
compileFile("../tests/run/blame_eye_triple_eee-double.scala", defaultOptimised) +
191-
compileFile("../tests/run/blame_eye_triple_eee-float.scala", defaultOptimised) +
192-
compileFile("../tests/run/run-bug4840.scala", defaultOptimised) +
193-
compileFile("../tests/run/optimizer-array-load.scala", defaultOptimised) +
194-
compileFile("../tests/run/constant-optimization.scala", defaultOptimised)
190+
compileFilesInDir("../tests/run-no-optimise", defaultOptions)
195191
}.checkRuns()
196192

197193
// Pickling Tests ------------------------------------------------------------
@@ -298,6 +294,13 @@ class CompilationTests extends ParallelTesting {
298294
tests.foreach(_.delete())
299295
}
300296

297+
@Test def testOptimised: Unit = {
298+
val outputDir = defaultOutputDir + "optimised/"
299+
compileFilesInDir("../tests/pos", defaultOptimised, outputDir).checkCompile()
300+
compileFilesInDir("../tests/run", defaultOptimised, outputDir).checkRuns()
301+
compileShallowFilesInDir("../tests/neg", defaultOptimised, outputDir).checkExpectedErrors()
302+
}
303+
301304
private val (compilerSources, backendSources, backendJvmSources) = {
302305
val compilerDir = Paths.get("../compiler/src")
303306
val compilerSources0 = sources(Files.walk(compilerDir))

compiler/test/dotty/tools/dotc/LinkOptimiseTests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import scala.concurrent.duration._
1313
import scala.collection.JavaConverters._
1414

1515
class LinkOptimiseTests extends ParallelTesting {
16+
import ParallelTesting._
1617
import TestConfiguration._
1718
import LinkOptimiseTests._
1819

compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,4 +970,32 @@ class ErrorMessagesTests extends ErrorMessagesTest {
970970
val MissingReturnTypeWithReturnStatement(method) :: Nil = messages
971971
assertEquals(method.name.show, "bad")
972972
}
973+
974+
@Test def noReturnInInline =
975+
checkMessagesAfter("frontend") {
976+
"""class BadFunction {
977+
| @inline def usesReturn: Int = { return 42 }
978+
|}
979+
""".stripMargin
980+
}.expect { (ictx, messages) =>
981+
implicit val ctx: Context = ictx
982+
983+
assertMessageCount(1, messages)
984+
985+
val NoReturnFromInline(method) :: Nil = messages
986+
assertEquals("method usesReturn", method.show)
987+
}
988+
989+
@Test def returnOutsideMethodDefinition =
990+
checkMessagesAfter("frontend") {
991+
"""object A {
992+
| return 5
993+
|}
994+
""".stripMargin
995+
}.expect { (ictx, messages) =>
996+
implicit val ctx: Context = ictx
997+
assertMessageCount(1, messages)
998+
val ReturnOutsideMethodDefinition(owner) :: Nil = messages
999+
assertEquals("object A", owner.show)
1000+
}
9731001
}

compiler/test/dotty/tools/vulpix/ParallelTesting.scala

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
10571057
}
10581058

10591059
/** Compiles a single file from the string path `f` using the supplied flags */
1060-
def compileFile(f: String, flags: TestFlags)(implicit outDirectory: String): CompilationTest = {
1060+
def compileFile(f: String, flags: TestFlags, outDirectory: String = defaultOutputDir): CompilationTest = {
10611061
val callingMethod = getCallingMethod()
10621062
val sourceFile = new JFile(f)
10631063
val parent = sourceFile.getParentFile
@@ -1087,7 +1087,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
10871087
* By default, files are compiled in alphabetical order. An optional seed
10881088
* can be used for randomization.
10891089
*/
1090-
def compileDir(f: String, flags: TestFlags, randomOrder: Option[Int] = None)(implicit outDirectory: String): CompilationTest = {
1090+
def compileDir(f: String, flags: TestFlags, randomOrder: Option[Int] = None, outDirectory: String = defaultOutputDir): CompilationTest = {
10911091
val callingMethod = getCallingMethod()
10921092
val outDir = outDirectory + callingMethod + "/"
10931093
val sourceDir = new JFile(f)
@@ -1116,7 +1116,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
11161116
* `testName` since files can be in separate directories and or be otherwise
11171117
* dissociated
11181118
*/
1119-
def compileList(testName: String, files: List[String], flags: TestFlags, callingMethod: String = getCallingMethod())(implicit outDirectory: String): CompilationTest = {
1119+
def compileList(testName: String, files: List[String], flags: TestFlags, callingMethod: String = getCallingMethod(), outDirectory: String = defaultOutputDir): CompilationTest = {
11201120
val outDir = outDirectory + callingMethod + "/" + testName + "/"
11211121

11221122
// Directories in which to compile all containing files with `flags`:
@@ -1147,7 +1147,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
11471147
* - Directories can have an associated check-file, where the check file has
11481148
* the same name as the directory (with the file extension `.check`)
11491149
*/
1150-
def compileFilesInDir(f: String, flags: TestFlags)(implicit outDirectory: String): CompilationTest = {
1150+
def compileFilesInDir(f: String, flags: TestFlags, outDirectory: String = defaultOutputDir): CompilationTest = {
11511151
val callingMethod = getCallingMethod()
11521152
val outDir = outDirectory + callingMethod + "/"
11531153
val sourceDir = new JFile(f)
@@ -1167,7 +1167,7 @@ trait ParallelTesting extends RunnerOrchestration { self =>
11671167
* sub-directories and as such, does **not** perform separate compilation
11681168
* tests.
11691169
*/
1170-
def compileShallowFilesInDir(f: String, flags: TestFlags)(implicit outDirectory: String): CompilationTest = {
1170+
def compileShallowFilesInDir(f: String, flags: TestFlags, outDirectory: String = defaultOutputDir): CompilationTest = {
11711171
val callingMethod = getCallingMethod()
11721172
val outDir = outDirectory + callingMethod + "/"
11731173
val sourceDir = new JFile(f)
@@ -1185,6 +1185,9 @@ trait ParallelTesting extends RunnerOrchestration { self =>
11851185
}
11861186

11871187
object ParallelTesting {
1188+
1189+
def defaultOutputDir: String = "../out/"
1190+
11881191
def isSourceFile(f: JFile): Boolean = {
11891192
val name = f.getName
11901193
name.endsWith(".scala") || name.endsWith(".java")

compiler/test/dotty/tools/vulpix/TestConfiguration.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package tools
33
package vulpix
44

55
object TestConfiguration {
6-
implicit val defaultOutputDir: String = "../out/"
76

87
val noCheckOptions = Array(
98
"-pagewidth", "120",

doc-tool/resources/_layouts/main.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,5 +61,12 @@
6161
}
6262
});
6363
</script>
64+
65+
<script>
66+
((window.gitter = {}).chat = {}).options = {
67+
room: 'lampepfl/dotty'
68+
};
69+
</script>
70+
<script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
6471
</body>
6572
</html>

doc-tool/resources/css/dottydoc.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,3 +270,7 @@ aside.success {
270270
border-left: 3px solid #36bf1d;
271271
background-color: #ebfddd;
272272
}
273+
274+
.gitter-open-chat-button {
275+
background-color: gray;
276+
}

doc-tool/src/dotty/tools/dottydoc/model/factories.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,9 @@ object factories {
120120

121121
case ref @ RefinedType(parent, rn, info) =>
122122
expandTpe(parent) //FIXME: will be a refined HK, aka class Foo[X] { def bar: List[X] } or similar
123+
124+
case ref: TypeArgRef =>
125+
expandTpe(ref.underlying)
123126
}
124127

125128
expandTpe(t)

project/Build.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ object Build {
871871

872872

873873
sbtPlugin := true,
874-
version := "0.1.5",
874+
version := "0.1.6-SNAPSHOT",
875875
ScriptedPlugin.scriptedSettings,
876876
ScriptedPlugin.sbtTestDirectory := baseDirectory.value / "sbt-test",
877877
ScriptedPlugin.scriptedBufferLog := false,

0 commit comments

Comments
 (0)