Skip to content

Commit 96fcdd9

Browse files
committed
Merge pull request #1238 from dotty-staging/fix-#1235
Three fixes prompted by #1235
2 parents 4d7aaf6 + d7c1c27 commit 96fcdd9

File tree

13 files changed

+98
-55
lines changed

13 files changed

+98
-55
lines changed

src/dotty/tools/dotc/Run.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class Run(comp: Compiler)(implicit ctx: Context) {
3535
compileSources(sources)
3636
} catch {
3737
case NonFatal(ex) =>
38-
ctx.println(i"exception occurred while compiling $units%, %")
38+
ctx.echo(i"exception occurred while compiling $units%, %")
3939
throw ex
4040
}
4141

@@ -74,8 +74,8 @@ class Run(comp: Compiler)(implicit ctx: Context) {
7474
val prevPhase = ctx.phase.prev // can be a mini-phase
7575
val squashedPhase = ctx.squashed(prevPhase)
7676

77-
ctx.println(s"result of $unit after ${squashedPhase}:")
78-
ctx.println(unit.tpdTree.show(ctx))
77+
ctx.echo(s"result of $unit after ${squashedPhase}:")
78+
ctx.echo(unit.tpdTree.show(ctx))
7979
}
8080

8181
def compile(sourceCode: String): Unit = {

src/dotty/tools/dotc/config/CompilerCommand.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,18 @@ object CompilerCommand extends DotClass {
110110

111111
if (summary.errors.nonEmpty) {
112112
summary.errors foreach (ctx.error(_))
113-
ctx.println(" dotc -help gives more information")
113+
ctx.echo(" dotc -help gives more information")
114114
Nil
115115
}
116116
else if (settings.version.value) {
117-
ctx.println(versionMsg)
117+
ctx.echo(versionMsg)
118118
Nil
119119
}
120120
else if (shouldStopWithInfo) {
121-
ctx.println(infoMessage)
121+
ctx.echo(infoMessage)
122122
Nil
123123
} else {
124-
if (sourcesRequired && summary.arguments.isEmpty) ctx.println(usageMessage)
124+
if (sourcesRequired && summary.arguments.isEmpty) ctx.echo(usageMessage)
125125
summary.arguments
126126
}
127127
}

src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,13 @@ class Definitions {
605605
}
606606

607607
def isBottomClass(cls: Symbol) = cls == NothingClass || cls == NullClass
608-
def isBottomType(tp: Type) = tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
608+
def isBottomType(tp: Type) = {
609+
def test(implicit ctx: Context) = tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
610+
try test
611+
catch { // See remark in SymDenotations#accessWithin
612+
case ex: NotDefinedHere => test(ctx.addMode(Mode.FutureDefsOK))
613+
}
614+
}
609615

610616
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
611617
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)

src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,7 @@ object Denotations {
464464
try info.signature
465465
catch { // !!! DEBUG
466466
case scala.util.control.NonFatal(ex) =>
467-
ctx.println(s"cannot take signature of ${info.show}")
467+
ctx.echo(s"cannot take signature of ${info.show}")
468468
throw ex
469469
}
470470
case _ => Signature.NotAMethod

src/dotty/tools/dotc/core/TypeComparer.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,8 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
715715
// val foo: C
716716
// foo.type <: C { type T = foo.T }
717717
rinfo2 match {
718-
case rinfo2: TypeAlias => (base select name) =:= rinfo2.alias
718+
case rinfo2: TypeAlias =>
719+
!defn.isBottomType(base.widen) && (base select name) =:= rinfo2.alias
719720
case _ => false
720721
}
721722
}
@@ -1295,10 +1296,10 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12951296
def showGoal(tp1: Type, tp2: Type)(implicit ctx: Context) = {
12961297
println(disambiguated(implicit ctx => s"assertion failure for ${tp1.show} <:< ${tp2.show}, frozen = $frozenConstraint"))
12971298
def explainPoly(tp: Type) = tp match {
1298-
case tp: PolyParam => ctx.println(s"polyparam ${tp.show} found in ${tp.binder.show}")
1299-
case tp: TypeRef if tp.symbol.exists => ctx.println(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
1300-
case tp: TypeVar => ctx.println(s"typevar ${tp.show}, origin = ${tp.origin}")
1301-
case _ => ctx.println(s"${tp.show} is a ${tp.getClass}")
1299+
case tp: PolyParam => ctx.echo(s"polyparam ${tp.show} found in ${tp.binder.show}")
1300+
case tp: TypeRef if tp.symbol.exists => ctx.echo(s"typeref ${tp.show} found in ${tp.symbol.owner.show}")
1301+
case tp: TypeVar => ctx.echo(s"typevar ${tp.show}, origin = ${tp.origin}")
1302+
case _ => ctx.echo(s"${tp.show} is a ${tp.getClass}")
13021303
}
13031304
explainPoly(tp1)
13041305
explainPoly(tp2)

src/dotty/tools/dotc/core/Types.scala

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2209,9 +2209,11 @@ object Types {
22092209
if (dependencyStatus == FalseDeps) { // dealias all false dependencies
22102210
val dealiasMap = new TypeMap {
22112211
def apply(tp: Type) = tp match {
2212-
case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) => // follow type alias to avoid dependency
2213-
val TypeAlias(alias) = tp.info
2214-
apply(alias)
2212+
case tp @ TypeRef(pre, name) =>
2213+
tp.info match {
2214+
case TypeAlias(alias) if depStatus(pre) == TrueDeps => apply(alias)
2215+
case _ => mapOver(tp)
2216+
}
22152217
case _ =>
22162218
mapOver(tp)
22172219
}
@@ -2222,10 +2224,31 @@ object Types {
22222224

22232225
var myDependencyStatus: DependencyStatus = Unknown
22242226

2225-
private def combine(x: DependencyStatus, y: DependencyStatus): DependencyStatus = {
2226-
val status = (x & StatusMask) max (y & StatusMask)
2227-
val provisional = (x | y) & Provisional
2228-
(if (status == TrueDeps) status else status | provisional).toByte
2227+
private def depStatus(tp: Type)(implicit ctx: Context): DependencyStatus = {
2228+
def combine(x: DependencyStatus, y: DependencyStatus) = {
2229+
val status = (x & StatusMask) max (y & StatusMask)
2230+
val provisional = (x | y) & Provisional
2231+
(if (status == TrueDeps) status else status | provisional).toByte
2232+
}
2233+
val depStatusAcc = new TypeAccumulator[DependencyStatus] {
2234+
def apply(status: DependencyStatus, tp: Type) =
2235+
if (status == TrueDeps) status
2236+
else
2237+
tp match {
2238+
case MethodParam(`thisMethodType`, _) => TrueDeps
2239+
case tp: TypeRef =>
2240+
val status1 = foldOver(status, tp)
2241+
tp.info match { // follow type alias to avoid dependency
2242+
case TypeAlias(alias) if status1 == TrueDeps && status != TrueDeps =>
2243+
combine(apply(status, alias), FalseDeps)
2244+
case _ =>
2245+
status1
2246+
}
2247+
case tp: TypeVar if !tp.isInstantiated => combine(status, Provisional)
2248+
case _ => foldOver(status, tp)
2249+
}
2250+
}
2251+
depStatusAcc(NoDeps, tp)
22292252
}
22302253

22312254
/** The dependency status of this method. Some examples:
@@ -2239,22 +2262,7 @@ object Types {
22392262
private def dependencyStatus(implicit ctx: Context): DependencyStatus = {
22402263
if (myDependencyStatus != Unknown) myDependencyStatus
22412264
else {
2242-
val isDepAcc = new TypeAccumulator[DependencyStatus] {
2243-
def apply(x: DependencyStatus, tp: Type) =
2244-
if (x == TrueDeps) x
2245-
else
2246-
tp match {
2247-
case MethodParam(`thisMethodType`, _) => TrueDeps
2248-
case tp @ TypeRef(MethodParam(`thisMethodType`, _), name) =>
2249-
tp.info match { // follow type alias to avoid dependency
2250-
case TypeAlias(alias) => combine(apply(x, alias), FalseDeps)
2251-
case _ => TrueDeps
2252-
}
2253-
case tp: TypeVar if !tp.isInstantiated => combine(x, Provisional)
2254-
case _ => foldOver(x, tp)
2255-
}
2256-
}
2257-
val result = isDepAcc(NoDeps, resType)
2265+
val result = depStatus(resType)
22582266
if ((result & Provisional) == 0) myDependencyStatus = result
22592267
(result & StatusMask).toByte
22602268
}

src/dotty/tools/dotc/reporting/Reporter.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ trait Reporting { this: Context =>
5151

5252
/** For sending messages that are printed only if -verbose is set */
5353
def inform(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
54-
if (this.settings.verbose.value) this.println(msg, pos)
54+
if (this.settings.verbose.value) this.echo(msg, pos)
5555

56-
def println(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
56+
def echo(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
5757
reporter.report(new Info(msg, pos))
5858

5959
def deprecationWarning(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
@@ -95,7 +95,7 @@ trait Reporting { this: Context =>
9595
*/
9696
def log(msg: => String, pos: SourcePosition = NoSourcePosition): Unit =
9797
if (this.settings.log.value.containsPhase(phase))
98-
this.println(s"[log ${ctx.phasesStack.reverse.mkString(" -> ")}] $msg", pos)
98+
echo(s"[log ${ctx.phasesStack.reverse.mkString(" -> ")}] $msg", pos)
9999

100100
def debuglog(msg: => String): Unit =
101101
if (ctx.debug) log(msg)
@@ -243,8 +243,7 @@ abstract class Reporter extends interfaces.ReporterResult {
243243
/** Print the summary of warnings and errors */
244244
def printSummary(implicit ctx: Context): Unit = {
245245
val s = summary
246-
if (s != "")
247-
ctx.println(s)
246+
if (s != "") ctx.echo(s)
248247
}
249248

250249
/** Returns a string meaning "n elements". */

src/dotty/tools/dotc/rewrite/Rewrites.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ object Rewrites {
7575
*/
7676
def writeBack()(implicit ctx: Context) =
7777
for (rewrites <- ctx.settings.rewrite.value; source <- rewrites.patched.keys) {
78-
ctx.println(s"[patched file ${source.file.path}]")
78+
ctx.echo(s"[patched file ${source.file.path}]")
7979
rewrites.patched(source).writeBack()
8080
}
8181
}

src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class TreeChecker extends Phase with SymTransformer {
5252
!name.exists(c => c == '.' || c == ';' || c =='[' || c == '/' || c == '<' || c == '>')
5353

5454
def printError(str: String)(implicit ctx: Context) = {
55-
ctx.println(Console.RED + "[error] " + Console.WHITE + str)
55+
ctx.echo(Console.RED + "[error] " + Console.WHITE + str)
5656
}
5757

5858
val NoSuperClass = Trait | Package
@@ -118,17 +118,17 @@ class TreeChecker extends Phase with SymTransformer {
118118
def check(phasesToRun: Seq[Phase], ctx: Context) = {
119119
val prevPhase = ctx.phase.prev // can be a mini-phase
120120
val squahsedPhase = ctx.squashed(prevPhase)
121-
ctx.println(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
121+
ctx.echo(s"checking ${ctx.compilationUnit} after phase ${squahsedPhase}")
122122
val checkingCtx = ctx.fresh.setReporter(new ThrowingReporter(ctx.reporter))
123123
val checker = new Checker(previousPhases(phasesToRun.toList)(ctx))
124124
try checker.typedExpr(ctx.compilationUnit.tpdTree)(checkingCtx)
125125
catch {
126126
case NonFatal(ex) => //TODO CHECK. Check that we are bootstrapped
127127
implicit val ctx: Context = checkingCtx
128-
ctx.println(i"*** error while checking ${ctx.compilationUnit} after phase ${checkingCtx.phase.prev} ***")
129-
ctx.println(ex.toString)
130-
ctx.println(ex.getStackTrace.take(30).deep.mkString("\n"))
131-
ctx.println("<<<")
128+
ctx.echo(i"*** error while checking ${ctx.compilationUnit} after phase ${checkingCtx.phase.prev} ***")
129+
ctx.echo(ex.toString)
130+
ctx.echo(ex.getStackTrace.take(30).deep.mkString("\n"))
131+
ctx.echo("<<<")
132132
throw ex
133133
}
134134
}
@@ -163,10 +163,10 @@ class TreeChecker extends Phase with SymTransformer {
163163
}
164164

165165
nowDefinedSyms += tree.symbol
166-
//ctx.println(i"defined: ${tree.symbol}")
166+
//ctx.echo(i"defined: ${tree.symbol}")
167167
val res = op
168168
nowDefinedSyms -= tree.symbol
169-
//ctx.println(i"undefined: ${tree.symbol}")
169+
//ctx.echo(i"undefined: ${tree.symbol}")
170170
res
171171
case _ => op
172172
}

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -736,8 +736,7 @@ trait Applications extends Compatibility { self: Typer =>
736736
}
737737

738738
unapplyFn.tpe.widen match {
739-
case mt: MethodType if mt.paramTypes.length == 1 && !mt.isDependent =>
740-
val m = mt
739+
case mt: MethodType if mt.paramTypes.length == 1 =>
741740
val unapplyArgType = mt.paramTypes.head
742741
unapp.println(i"unapp arg tpe = $unapplyArgType, pt = $selType")
743742
def wpt = widenForMatchSelector(selType) // needed?
@@ -778,7 +777,7 @@ trait Applications extends Compatibility { self: Typer =>
778777
tree.pos)
779778
}
780779

781-
val dummyArg = dummyTreeOfType(unapplyArgType)
780+
val dummyArg = dummyTreeOfType(ownType)
782781
val unapplyApp = typedExpr(untpd.TypedSplice(Apply(unapplyFn, dummyArg :: Nil)))
783782
val unapplyImplicits = unapplyApp match {
784783
case Apply(Apply(unapply, `dummyArg` :: Nil), args2) => assert(args2.nonEmpty); args2

src/dotty/tools/dotc/typer/FrontEnd.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class FrontEnd extends Phase {
2323
try body
2424
catch {
2525
case NonFatal(ex) =>
26-
ctx.println(s"exception occurred while $doing ${ctx.compilationUnit}")
26+
ctx.echo(s"exception occurred while $doing ${ctx.compilationUnit}")
2727
throw ex
2828
}
2929

tests/pos/dependent-extractors.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
object Test {
2+
3+
abstract class C { type T; val x: T }
4+
5+
val c = new C { type T = Int; val x = 1 }
6+
7+
object X { def unapply(x: C): Some[x.T] = Some(x.x) }
8+
9+
val y = c match { case X(y) => y }
10+
val y1: Int = y
11+
12+
val z = (c: Any) match { case X(y) => y }
13+
val z1: C#T = z
14+
}

tests/pos/i1235.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
case class LazyList[T](headThunk: () => T, tailThunk: () => LazyList[T]){
2+
lazy val head = headThunk()
3+
lazy val tail = tailThunk()
4+
}
5+
6+
object ~: {
7+
def unapply[T](x: LazyList[T]) = Some((x.head, x.tail))
8+
}
9+
10+
object MinimizedMatchFail {
11+
val ll = LazyList(() => 1, () => LazyList(() => 2, () => ???))
12+
13+
ll match {
14+
case lb ~: rest => println("success")
15+
}
16+
}

0 commit comments

Comments
 (0)