diff options
-rw-r--r-- | src/dotty/tools/dotc/Run.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/config/CompilerCommand.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 11 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 54 | ||||
-rw-r--r-- | src/dotty/tools/dotc/reporting/Reporter.scala | 9 | ||||
-rw-r--r-- | src/dotty/tools/dotc/rewrite/Rewrites.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 16 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/FrontEnd.scala | 2 | ||||
-rw-r--r-- | tests/pos/dependent-extractors.scala | 14 | ||||
-rw-r--r-- | tests/pos/i1235.scala | 16 |
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") + } +} |