Skip to content

Commit 8cc0b81

Browse files
committed
Rearrange TypeError exceptions
- Move them all to TypeErrors.scala - Systematically use `toMessage` for reporting - Catch stack overflows instead of counting recursions
1 parent e49bf81 commit 8cc0b81

File tree

9 files changed

+14
-96
lines changed

9 files changed

+14
-96
lines changed

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ class ScalaSettings extends Settings.SettingGroup {
7474
val XmainClass = StringSetting("-Xmain-class", "path", "Class for manifest's Main-Class entry (only useful with -d <jar>)", "")
7575
val XnoValueClasses = BooleanSetting("-Xno-value-classes", "Do not use value classes. Helps debugging.")
7676
val XreplLineWidth = IntSetting("-Xrepl-line-width", "Maximal number of columns per line for REPL output", 390)
77-
val XmaxMemberRecursions = IntSetting("-Xmax-member-recursions", "Maximal number of recursive calls to find-member", 100)
7877
val XfatalWarnings = BooleanSetting("-Xfatal-warnings", "Fail the compilation if there are any warnings.")
7978
val XverifySignatures = BooleanSetting("-Xverify-signatures", "Verify generic signatures in generated bytecode.")
8079

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

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import util.Positions.{Position, NoPosition}
2020
import util.Stats._
2121
import util.{DotClass, SimpleIdentitySet}
2222
import reporting.diagnostic.Message
23-
import reporting.diagnostic.messages.CyclicReferenceInvolving
2423
import ast.tpd._
2524
import ast.TreeTypeMap
2625
import printing.Texts._
@@ -32,10 +31,9 @@ import Uniques._
3231
import collection.{mutable, Seq, breakOut}
3332
import config.Config
3433
import annotation.tailrec
35-
import Flags.FlagSet
3634
import language.implicitConversions
3735
import scala.util.hashing.{ MurmurHash3 => hashing }
38-
import config.Printers.{core, typr, cyclicErrors}
36+
import config.Printers.{core, typr}
3937
import java.lang.ref.WeakReference
4038

4139
object Types {
@@ -647,17 +645,14 @@ object Types {
647645
}
648646

649647
val recCount = ctx.findMemberCount
650-
if (recCount >= Config.LogPendingFindMemberThreshold) {
651-
if (ctx.findMemberCount > ctx.settings.XmaxMemberRecursions.value)
652-
throw new CyclicFindMember(pre, name)
648+
if (recCount >= Config.LogPendingFindMemberThreshold)
653649
ctx.pendingMemberSearches = name :: ctx.pendingMemberSearches
654-
}
655650
ctx.findMemberCount = recCount + 1
656651
try go(this)
657652
catch {
658653
case ex: Throwable =>
659654
core.println(s"findMember exception for $this member $name, pre = $pre, recCount = $recCount")
660-
throw ex // DEBUG
655+
throw new RecursionOverflow("find-member", pre, name, ex)
661656
}
662657
finally {
663658
if (recCount >= Config.LogPendingFindMemberThreshold)
@@ -4546,56 +4541,6 @@ object Types {
45464541
def apply(pre: Type, name: Name)(implicit ctx: Context): Boolean = true
45474542
}
45484543

4549-
// ----- Exceptions -------------------------------------------------------------
4550-
4551-
class TypeError(msg: String) extends Exception(msg)
4552-
4553-
class MalformedType(pre: Type, denot: Denotation, absMembers: Set[Name])
4554-
extends TypeError(
4555-
s"malformed type: $pre is not a legal prefix for $denot because it contains abstract type member${if (absMembers.size == 1) "" else "s"} ${absMembers.mkString(", ")}")
4556-
4557-
class MissingType(pre: Type, name: Name)(implicit ctx: Context) extends TypeError(
4558-
i"""cannot resolve reference to type $pre.$name
4559-
|the classfile defining the type might be missing from the classpath${otherReason(pre)}""") {
4560-
if (ctx.debug) printStackTrace()
4561-
}
4562-
4563-
def showPrefixSafely(pre: Type)(implicit ctx: Context): String = pre.stripTypeVar match {
4564-
case pre: TermRef => i"${pre.termSymbol.name}."
4565-
case pre: TypeRef => i"${pre.typeSymbol.name}#"
4566-
case pre: TypeProxy => showPrefixSafely(pre.underlying)
4567-
case _ => if (pre.typeSymbol.exists) i"${pre.typeSymbol.name}#" else "."
4568-
}
4569-
4570-
class CyclicFindMember(pre: Type, name: Name)(implicit ctx: Context) extends TypeError(
4571-
i"""member search for ${showPrefixSafely(pre)}$name too deep.
4572-
|searches, from inner to outer: .${ctx.pendingMemberSearches}% .%""")
4573-
4574-
private def otherReason(pre: Type)(implicit ctx: Context): String = pre match {
4575-
case pre: ThisType if pre.cls.givenSelfType.exists =>
4576-
i"\nor the self type of $pre might not contain all transitive dependencies"
4577-
case _ => ""
4578-
}
4579-
4580-
class CyclicReference private (val denot: SymDenotation)
4581-
extends TypeError(s"cyclic reference involving $denot") {
4582-
def toMessage(implicit ctx: Context) = CyclicReferenceInvolving(denot)
4583-
}
4584-
4585-
object CyclicReference {
4586-
def apply(denot: SymDenotation)(implicit ctx: Context): CyclicReference = {
4587-
val ex = new CyclicReference(denot)
4588-
if (!(ctx.mode is Mode.CheckCyclic)) {
4589-
cyclicErrors.println(ex.getMessage)
4590-
for (elem <- ex.getStackTrace take 200)
4591-
cyclicErrors.println(elem.toString)
4592-
}
4593-
ex
4594-
}
4595-
}
4596-
4597-
class MergeError(msg: String, val tp1: Type, val tp2: Type) extends TypeError(msg)
4598-
45994544
// ----- Debug ---------------------------------------------------------
46004545

46014546
@sharable var debugTrace = false

compiler/src/dotty/tools/dotc/sbt/ExtractAPI.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import Symbols._
1414
import NameOps._
1515
import NameKinds.DefaultGetterName
1616
import typer.Inliner
17-
import typer.ErrorReporting.cyclicErrorMsg
1817
import transform.ValueClasses
1918
import transform.SymUtils._
2019
import dotty.tools.io.File
@@ -243,10 +242,10 @@ private class ExtractAPICollector(implicit val ctx: Context) extends ThunkHolder
243242
val ancestorTypes0 =
244243
try linearizedAncestorTypes(cinfo)
245244
catch {
246-
case ex: CyclicReference =>
245+
case ex: TypeError =>
247246
// See neg/i1750a for an example where a cyclic error can arise.
248247
// The root cause in this example is an illegal "override" of an inner trait
249-
ctx.error(cyclicErrorMsg(ex), csym.pos)
248+
ctx.error(ex.toMessage, csym.pos)
250249
defn.ObjectType :: Nil
251250
}
252251
if (ValueClasses.isDerivedValueClass(csym)) {

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import Flags._, Symbols._, Contexts._, Types._, Scopes._, Decorators._
66
import util.HashSet
77
import collection.mutable
88
import collection.immutable.BitSet
9-
import typer.ErrorReporting.cyclicErrorMsg
109
import scala.annotation.tailrec
1110

1211
/** A module that can produce a kind of iterator (`Cursor`),
@@ -133,10 +132,10 @@ object OverridingPairs {
133132
}
134133
}
135134
catch {
136-
case ex: CyclicReference =>
135+
case ex: TypeError =>
137136
// See neg/i1750a for an example where a cyclic error can arise.
138137
// The root cause in this example is an illegal "override" of an inner trait
139-
ctx.error(cyclicErrorMsg(ex), base.pos)
138+
ctx.error(ex.toMessage, base.pos)
140139
}
141140
} else {
142141
curEntry = curEntry.prev

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

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -352,18 +352,15 @@ object Checking {
352352
val mbr = joint.member(name)
353353
mbr.info match {
354354
case bounds: TypeBounds =>
355-
val res = checkNonCyclic(mbr.symbol, bounds, reportErrors = true).isError
356-
if (res)
357-
println(i"cyclic ${mbr.symbol}, $bounds -> $res")
358-
res
355+
!checkNonCyclic(mbr.symbol, bounds, reportErrors = true).isError
359356
case _ =>
360-
false
357+
true
361358
}
362359
}
363360
catch {
364-
case ex: CyclicFindMember =>
361+
case ex: RecursionOverflow =>
365362
ctx.error(em"cyclic reference involving type $name", pos)
366-
true
363+
false
367364
}
368365
}
369366

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

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,6 @@ object ErrorReporting {
2323
ErrorType(msg)
2424
}
2525

26-
def cyclicErrorMsg(ex: CyclicReference)(implicit ctx: Context) = {
27-
val cycleSym = ex.denot.symbol
28-
def errorMsg(msg: Message, cx: Context): Message =
29-
if (cx.mode is Mode.InferringReturnType) {
30-
cx.tree match {
31-
case tree: untpd.DefDef if !tree.tpt.typeOpt.exists =>
32-
OverloadedOrRecursiveMethodNeedsResultType(tree.name)
33-
case tree: untpd.ValDef if !tree.tpt.typeOpt.exists =>
34-
RecursiveValueNeedsResultType(tree.name)
35-
case _ =>
36-
errorMsg(msg, cx.outer)
37-
}
38-
} else msg
39-
40-
if (cycleSym.is(Implicit, butNot = Method) && cycleSym.owner.isTerm)
41-
CyclicReferenceInvolvingImplicit(cycleSym)
42-
else
43-
errorMsg(ex.toMessage, ctx)
44-
}
45-
4626
def wrongNumberOfTypeArgs(fntpe: Type, expectedArgs: List[ParamInfo], actual: List[untpd.Tree], pos: Position)(implicit ctx: Context) =
4727
errorType(WrongNumberOfTypeArgs(fntpe, expectedArgs, actual)(ctx), pos)
4828

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1615,7 +1615,7 @@ class RefChecks extends MiniPhase { thisPhase =>
16151615
} catch {
16161616
case ex: TypeError =>
16171617
if (settings.debug) ex.printStackTrace()
1618-
unit.error(tree.pos, ex.getMessage())
1618+
unit.error(tree.pos, ex.toMssage)
16191619
tree
16201620
} finally {
16211621
localTyper = savedLocalTyper

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,8 +1861,7 @@ class Typer extends Namer
18611861
assertPositioned(tree)
18621862
try adapt(typedUnadapted(tree, pt, locked), pt, locked)
18631863
catch {
1864-
case ex: CyclicReference => errorTree(tree, cyclicErrorMsg(ex))
1865-
case ex: TypeError => errorTree(tree, ex.getMessage)
1864+
case ex: TypeError => errorTree(tree, ex.toMessage)
18661865
}
18671866
}
18681867

tests/neg/i4368.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ object Test7 {
110110
object Test8 {
111111
112112
class A {
113-
type T = B#U // error: cyclic
113+
type T = B#U
114114
}
115115
116116
class B {

0 commit comments

Comments
 (0)