aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-04-28 10:43:59 +0200
committerodersky <odersky@gmail.com>2016-04-28 10:43:59 +0200
commit96fcdd9da51e1febe9e320f774424b5ac3f8ff3d (patch)
tree0dcca4fb37ba79d531567789bf3600997ade0684
parent4d7aaf637edafa1305602fc9f63b4c2ed4288ad5 (diff)
parentd7c1c27b0765b33811326e3cf02dcd4aa12b6cd8 (diff)
downloaddotty-96fcdd9da51e1febe9e320f774424b5ac3f8ff3d.tar.gz
dotty-96fcdd9da51e1febe9e320f774424b5ac3f8ff3d.tar.bz2
dotty-96fcdd9da51e1febe9e320f774424b5ac3f8ff3d.zip
Merge pull request #1238 from dotty-staging/fix-#1235
Three fixes prompted by #1235
-rw-r--r--src/dotty/tools/dotc/Run.scala6
-rw-r--r--src/dotty/tools/dotc/config/CompilerCommand.scala8
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala8
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala11
-rw-r--r--src/dotty/tools/dotc/core/Types.scala54
-rw-r--r--src/dotty/tools/dotc/reporting/Reporter.scala9
-rw-r--r--src/dotty/tools/dotc/rewrite/Rewrites.scala2
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala16
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala5
-rw-r--r--src/dotty/tools/dotc/typer/FrontEnd.scala2
-rw-r--r--tests/pos/dependent-extractors.scala14
-rw-r--r--tests/pos/i1235.scala16
13 files changed, 98 insertions, 55 deletions
diff --git a/src/dotty/tools/dotc/Run.scala b/src/dotty/tools/dotc/Run.scala
index 7a0e555e4..928a59214 100644
--- a/src/dotty/tools/dotc/Run.scala
+++ b/src/dotty/tools/dotc/Run.scala
@@ -35,7 +35,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
compileSources(sources)
} catch {
case NonFatal(ex) =>
- ctx.println(i"exception occurred while compiling $units%, %")
+ ctx.echo(i"exception occurred while compiling $units%, %")
throw ex
}
@@ -74,8 +74,8 @@ class Run(comp: Compiler)(implicit ctx: Context) {
val prevPhase = ctx.phase.prev // can be a mini-phase
val squashedPhase = ctx.squashed(prevPhase)
- ctx.println(s"result of $unit after ${squashedPhase}:")
- ctx.println(unit.tpdTree.show(ctx))
+ ctx.echo(s"result of $unit after ${squashedPhase}:")
+ ctx.echo(unit.tpdTree.show(ctx))
}
def compile(sourceCode: String): Unit = {
diff --git a/src/dotty/tools/dotc/config/CompilerCommand.scala b/src/dotty/tools/dotc/config/CompilerCommand.scala
index e34ca07f9..2fe32b4d3 100644
--- a/src/dotty/tools/dotc/config/CompilerCommand.scala
+++ b/src/dotty/tools/dotc/config/CompilerCommand.scala
@@ -110,18 +110,18 @@ object CompilerCommand extends DotClass {
if (summary.errors.nonEmpty) {
summary.errors foreach (ctx.error(_))
- ctx.println(" dotc -help gives more information")
+ ctx.echo(" dotc -help gives more information")
Nil
}
else if (settings.version.value) {
- ctx.println(versionMsg)
+ ctx.echo(versionMsg)
Nil
}
else if (shouldStopWithInfo) {
- ctx.println(infoMessage)
+ ctx.echo(infoMessage)
Nil
} else {
- if (sourcesRequired && summary.arguments.isEmpty) ctx.println(usageMessage)
+ if (sourcesRequired && summary.arguments.isEmpty) ctx.echo(usageMessage)
summary.arguments
}
}
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 9128bd3a5..7f59cbed0 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -605,7 +605,13 @@ class Definitions {
}
def isBottomClass(cls: Symbol) = cls == NothingClass || cls == NullClass
- def isBottomType(tp: Type) = tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
+ def isBottomType(tp: Type) = {
+ def test(implicit ctx: Context) = tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
+ try test
+ catch { // See remark in SymDenotations#accessWithin
+ case ex: NotDefinedHere => test(ctx.addMode(Mode.FutureDefsOK))
+ }
+ }
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index 6e7eed3bc..946738d73 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -464,7 +464,7 @@ object Denotations {
try info.signature
catch { // !!! DEBUG
case scala.util.control.NonFatal(ex) =>
- ctx.println(s"cannot take signature of ${info.show}")
+ ctx.echo(s"cannot take signature of ${info.show}")
throw ex
}
case _ => Signature.NotAMethod
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index dbee86549..2523c6b9a 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -715,7 +715,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
// val foo: C
// foo.type <: C { type T = foo.T }
rinfo2 match {
- case rinfo2: TypeAlias => (base select name) =:= rinfo2.alias
+ case rinfo2: TypeAlias =>
+ !defn.isBottomType(base.widen) && (base select name) =:= rinfo2.alias
case _ => false
}
}
@@ -1295,10 +1296,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
def showGoal(tp1: Type, tp2: Type)(implicit ctx: Context) = {
println(disambiguated(implicit ctx => s"assertion failure for ${tp1.show} <:< ${tp2.show}, frozen = $frozenConstraint"))
def explainPoly(tp: Type) = tp match {
- case tp: PolyParam => ctx.println(s"polyparam ${tp.show} found in ${tp.binder.show}")
- case tp: TypeRef if tp.symbol.exists => ctx.println(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
- case tp: TypeVar => ctx.println(s"typevar ${tp.show}, origin = ${tp.origin}")
- case _ => ctx.println(s"${tp.show} is a ${tp.getClass}")
+ case tp: PolyParam => ctx.echo(s"polyparam ${tp.show} found in ${tp.binder.show}")
+ case tp: TypeRef if tp.symbol.exists => ctx.echo(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
+ case tp: TypeVar => ctx.echo(s"typevar ${tp.show}, origin = ${tp.origin}")
+ case _ => ctx.echo(s"${tp.show} is a ${tp.getClass}")
}
explainPoly(tp1)
explainPoly(tp2)
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 913339409..8ef0e9fd1 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2209,9 +2209,11 @@ object Types {
if (dependencyStatus == FalseDeps) { // dealias all false dependencies
val dealiasMap = new TypeMap {
def apply(tp: Type) = tp match {
- case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) => // follow type alias to avoid dependency
- val TypeAlias(alias) = tp.info
- apply(alias)
+ case tp @ TypeRef(pre, name) =>
+ tp.info match {
+ case TypeAlias(alias) if depStatus(pre) == TrueDeps => apply(alias)
+ case _ => mapOver(tp)
+ }
case _ =>
mapOver(tp)
}
@@ -2222,10 +2224,31 @@ object Types {
var myDependencyStatus: DependencyStatus = Unknown
- private def combine(x: DependencyStatus, y: DependencyStatus): DependencyStatus = {
- val status = (x & StatusMask) max (y & StatusMask)
- val provisional = (x | y) & Provisional
- (if (status == TrueDeps) status else status | provisional).toByte
+ private def depStatus(tp: Type)(implicit ctx: Context): DependencyStatus = {
+ def combine(x: DependencyStatus, y: DependencyStatus) = {
+ val status = (x & StatusMask) max (y & StatusMask)
+ val provisional = (x | y) & Provisional
+ (if (status == TrueDeps) status else status | provisional).toByte
+ }
+ val depStatusAcc = new TypeAccumulator[DependencyStatus] {
+ def apply(status: DependencyStatus, tp: Type) =
+ if (status == TrueDeps) status
+ else
+ tp match {
+ case MethodParam(`thisMethodType`, _) => TrueDeps
+ case tp: TypeRef =>
+ val status1 = foldOver(status, tp)
+ tp.info match { // follow type alias to avoid dependency
+ case TypeAlias(alias) if status1 == TrueDeps && status != TrueDeps =>
+ combine(apply(status, alias), FalseDeps)
+ case _ =>
+ status1
+ }
+ case tp: TypeVar if !tp.isInstantiated => combine(status, Provisional)
+ case _ => foldOver(status, tp)
+ }
+ }
+ depStatusAcc(NoDeps, tp)
}
/** The dependency status of this method. Some examples:
@@ -2239,22 +2262,7 @@ object Types {
private def dependencyStatus(implicit ctx: Context): DependencyStatus = {
if (myDependencyStatus != Unknown) myDependencyStatus
else {
- val isDepAcc = new TypeAccumulator[DependencyStatus] {
- def apply(x: DependencyStatus, tp: Type) =
- if (x == TrueDeps) x
- else
- tp match {
- case MethodParam(`thisMethodType`, _) => TrueDeps
- case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) =>
- tp.info match { // follow type alias to avoid dependency
- case TypeAlias(alias) => combine(apply(x, alias), FalseDeps)
- case _ => TrueDeps
- }
- case tp: TypeVar if !tp.isInstantiated => combine(x, Provisional)
- case _ => foldOver(x, tp)
- }
- }
- val result = isDepAcc(NoDeps, resType)
+ val result = depStatus(resType)
if ((result & Provisional) == 0) myDependencyStatus = result
(result & StatusMask).toByte
}
diff --git a/src/dotty/tools/dotc/reporting/Reporter.scala b/src/dotty/tools/dotc/reporting/Reporter.scala
index 44defa6b1..e4169b1fd 100644
--- a/src/dotty/tools/dotc/reporting/Reporter.scala
+++ b/src/dotty/tools/dotc/reporting/Reporter.scala
@@ -51,9 +51,9 @@ trait Reporting { this: Context =>
/** For sending messages that are printed only if -verbose is set */
def inform(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
- if (this.settings.verbose.value) this.println(msg, pos)
+ if (this.settings.verbose.value) this.echo(msg, pos)
- def println(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
+ def echo(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
reporter.report(new Info(msg, pos))
def deprecationWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
@@ -95,7 +95,7 @@ trait Reporting { this: Context =>
*/
def log(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
if (this.settings.log.value.containsPhase(phase))
- this.println(s"[log ${ctx.phasesStack.reverse.mkString(" -> ")}] $msg", pos)
+ echo(s"[log ${ctx.phasesStack.reverse.mkString(" -> ")}] $msg", pos)
def debuglog(msg: => String): Unit =
if (ctx.debug) log(msg)
@@ -243,8 +243,7 @@ abstract class Reporter extends interfaces.ReporterResult {
/** Print the summary of warnings and errors */
def printSummary(implicit ctx: Context): Unit = {
val s = summary
- if (s != "")
- ctx.println(s)
+ if (s != "") ctx.echo(s)
}
/** Returns a string meaning "n elements". */
diff --git a/src/dotty/tools/dotc/rewrite/Rewrites.scala b/src/dotty/tools/dotc/rewrite/Rewrites.scala
index 7ab0e5d59..c42c808fe 100644
--- a/src/dotty/tools/dotc/rewrite/Rewrites.scala
+++ b/src/dotty/tools/dotc/rewrite/Rewrites.scala
@@ -75,7 +75,7 @@ object Rewrites {
*/
def writeBack()(implicit ctx: Context) =
for (rewrites <- ctx.settings.rewrite.value; source <- rewrites.patched.keys) {
- ctx.println(s"[patched file ${source.file.path}]")
+ ctx.echo(s"[patched file ${source.file.path}]")
rewrites.patched(source).writeBack()
}
}
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index f11789c9a..a27c9c5f3 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -52,7 +52,7 @@ class TreeChecker extends Phase with SymTransformer {
!name.exists(c => c == '.' || c == ';' || c =='[' || c == '/' || c == '<' || c == '>')
def printError(str: String)(implicit ctx: Context) = {
- ctx.println(Console.RED + "[error] " + Console.WHITE + str)
+ ctx.echo(Console.RED + "[error] " + Console.WHITE + str)
}
val NoSuperClass = Trait | Package
@@ -118,17 +118,17 @@ class TreeChecker extends Phase with SymTransformer {
def check(phasesToRun: Seq[Phase], ctx: Context) = {
val prevPhase = ctx.phase.prev // can be a mini-phase
val squahsedPhase = ctx.squashed(prevPhase)
- ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
+ ctx.echo(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
val checkingCtx = ctx.fresh.setReporter(new ThrowingReporter(ctx.reporter))
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
catch {
case NonFatal(ex) => //TODO CHECK. Check that we are bootstrapped
implicit val ctx: Context = checkingCtx
- ctx.println(i"*** error while checking ${ctx.compilationUnit} after phase ${checkingCtx.phase.prev} ***")
- ctx.println(ex.toString)
- ctx.println(ex.getStackTrace.take(30).deep.mkString("\n"))
- ctx.println("<<<")
+ ctx.echo(i"*** error while checking ${ctx.compilationUnit} after phase ${checkingCtx.phase.prev} ***")
+ ctx.echo(ex.toString)
+ ctx.echo(ex.getStackTrace.take(30).deep.mkString("\n"))
+ ctx.echo("<<<")
throw ex
}
}
@@ -163,10 +163,10 @@ class TreeChecker extends Phase with SymTransformer {
}
nowDefinedSyms += tree.symbol
- //ctx.println(i"defined: ${tree.symbol}")
+ //ctx.echo(i"defined: ${tree.symbol}")
val res = op
nowDefinedSyms -= tree.symbol
- //ctx.println(i"undefined: ${tree.symbol}")
+ //ctx.echo(i"undefined: ${tree.symbol}")
res
case _ => op
}
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 37a9f0ba0..d70546f9d 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -736,8 +736,7 @@ trait Applications extends Compatibility { self: Typer =>
}
unapplyFn.tpe.widen match {
- case mt: MethodType if mt.paramTypes.length == 1 && !mt.isDependent =>
- val m = mt
+ case mt: MethodType if mt.paramTypes.length == 1 =>
val unapplyArgType = mt.paramTypes.head
unapp.println(i"unapp arg tpe = $unapplyArgType, pt = $selType")
def wpt = widenForMatchSelector(selType) // needed?
@@ -778,7 +777,7 @@ trait Applications extends Compatibility { self: Typer =>
tree.pos)
}
- val dummyArg = dummyTreeOfType(unapplyArgType)
+ val dummyArg = dummyTreeOfType(ownType)
val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
val unapplyImplicits = unapplyApp match {
case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); args2
diff --git a/src/dotty/tools/dotc/typer/FrontEnd.scala b/src/dotty/tools/dotc/typer/FrontEnd.scala
index eee8744a5..c5c6aec3c 100644
--- a/src/dotty/tools/dotc/typer/FrontEnd.scala
+++ b/src/dotty/tools/dotc/typer/FrontEnd.scala
@@ -23,7 +23,7 @@ class FrontEnd extends Phase {
try body
catch {
case NonFatal(ex) =>
- ctx.println(s"exception occurred while $doing ${ctx.compilationUnit}")
+ ctx.echo(s"exception occurred while $doing ${ctx.compilationUnit}")
throw ex
}
diff --git a/tests/pos/dependent-extractors.scala b/tests/pos/dependent-extractors.scala
new file mode 100644
index 000000000..4d0830155
--- /dev/null
+++ b/tests/pos/dependent-extractors.scala
@@ -0,0 +1,14 @@
+object Test {
+
+ abstract class C { type T; val x: T }
+
+ val c = new C { type T = Int; val x = 1 }
+
+ object X { def unapply(x: C): Some[x.T] = Some(x.x) }
+
+ val y = c match { case X(y) => y }
+ val y1: Int = y
+
+ val z = (c: Any) match { case X(y) => y }
+ val z1: C#T = z
+}
diff --git a/tests/pos/i1235.scala b/tests/pos/i1235.scala
new file mode 100644
index 000000000..1fbb82ac1
--- /dev/null
+++ b/tests/pos/i1235.scala
@@ -0,0 +1,16 @@
+case class LazyList[T](headThunk: () => T, tailThunk: () => LazyList[T]){
+ lazy val head = headThunk()
+ lazy val tail = tailThunk()
+}
+
+object ~: {
+ def unapply[T](x: LazyList[T]) = Some((x.head, x.tail))
+}
+
+object MinimizedMatchFail {
+ val ll = LazyList(() => 1, () => LazyList(() => 2, () => ???))
+
+ ll match {
+ case lb ~: rest => println("success")
+ }
+}