diff options
author | Martin Odersky <odersky@gmail.com> | 2016-08-21 11:07:52 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-08-21 15:19:27 +0200 |
commit | 1b2fc1f016f837ca51c7627d359ed88e24692df6 (patch) | |
tree | c28871d654d6e9173672ad4d049c3100bc535ee4 | |
parent | ac423a31548cfd0901559513e020331facf66a89 (diff) | |
download | dotty-1b2fc1f016f837ca51c7627d359ed88e24692df6.tar.gz dotty-1b2fc1f016f837ca51c7627d359ed88e24692df6.tar.bz2 dotty-1b2fc1f016f837ca51c7627d359ed88e24692df6.zip |
Don't force in isErronous check
isErroneous forced LazyRefs through the `existsPart` combinator. This
might prompt further errors or infinite recursions, so should be avoided.
Seen in the wild when trying to trace t1756.scala with -Ylog:front and typr printer on.
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 1bfd6eaee..115995ddc 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -177,7 +177,7 @@ object Types { } /** Is some part of this type produced as a repair for an error? */ - final def isErroneous(implicit ctx: Context): Boolean = existsPart(_.isError) + final def isErroneous(implicit ctx: Context): Boolean = existsPart(_.isError, forceLazy = false) /** Does the type carry an annotation that is an instance of `cls`? */ final def hasAnnotation(cls: ClassSymbol)(implicit ctx: Context): Boolean = stripTypeVar match { @@ -219,8 +219,8 @@ object Types { /** Returns true if there is a part of this type that satisfies predicate `p`. */ - final def existsPart(p: Type => Boolean)(implicit ctx: Context): Boolean = - new ExistsAccumulator(p).apply(false, this) + final def existsPart(p: Type => Boolean, forceLazy: Boolean = true)(implicit ctx: Context): Boolean = + new ExistsAccumulator(p, forceLazy).apply(false, this) /** Returns true if all parts of this type satisfy predicate `p`. */ @@ -3688,9 +3688,10 @@ object Types { protected def traverseChildren(tp: Type) = foldOver((), tp) } - class ExistsAccumulator(p: Type => Boolean)(implicit ctx: Context) extends TypeAccumulator[Boolean] { + class ExistsAccumulator(p: Type => Boolean, forceLazy: Boolean = true)(implicit ctx: Context) extends TypeAccumulator[Boolean] { override def stopAtStatic = false - def apply(x: Boolean, tp: Type) = x || p(tp) || foldOver(x, tp) + def apply(x: Boolean, tp: Type) = + x || p(tp) || (forceLazy || !tp.isInstanceOf[LazyRef]) && foldOver(x, tp) } class ForeachAccumulator(p: Type => Unit)(implicit ctx: Context) extends TypeAccumulator[Unit] { |