summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc')
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala11
4 files changed, 48 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 9c9be4eb4d..464fa1ad18 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -185,6 +185,19 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
}
+ private var propCnt = 0
+ @inline final def withPropagateCyclicReferences[T](t: => T): T = {
+ try {
+ propCnt = propCnt+1
+ t
+ } finally {
+ propCnt = propCnt-1
+ assert(propCnt >= 0)
+ }
+ }
+
+ def propagateCyclicReferences: Boolean = propCnt > 0
+
/** Representing ASTs as graphs */
object treeBrowsers extends {
val global: Global.this.type = Global.this
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index fcfcc8feb9..2d8d591b6d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -655,9 +655,6 @@ trait ContextErrors {
def ParentFinalInheritanceError(parent: Tree, mixin: Symbol) =
NormalTypeError(parent, "illegal inheritance from final "+mixin)
- def ParentSealedInheritanceError(parent: Tree, psym: Symbol) =
- NormalTypeError(parent, "illegal inheritance from sealed " + psym )
-
def ParentSelfTypeConformanceError(parent: Tree, selfType: Type) =
NormalTypeError(parent,
"illegal inheritance;\n self-type "+selfType+" does not conform to "+
@@ -1172,6 +1169,9 @@ trait ContextErrors {
def MissingParameterOrValTypeError(vparam: Tree) =
issueNormalTypeError(vparam, "missing parameter type")
+ def ParentSealedInheritanceError(parent: Tree, psym: Symbol) =
+ NormalTypeError(parent, "illegal inheritance from sealed " + psym )
+
def RootImportError(tree: Tree) =
issueNormalTypeError(tree, "_root_ cannot be imported")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 78e8c8c073..7ffc6c6b48 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -115,7 +115,7 @@ trait Namers extends MethodSynthesis {
protected def owner = context.owner
def contextFile = context.unit.source.file
def typeErrorHandler[T](tree: Tree, alt: T): PartialFunction[Throwable, T] = {
- case ex: TypeError =>
+ case ex: TypeError if !global.propagateCyclicReferences =>
// H@ need to ensure that we handle only cyclic references
TypeSigError(tree, ex)
alt
@@ -1028,12 +1028,33 @@ trait Namers extends MethodSynthesis {
private def templateSig(templ: Template): Type = {
val clazz = context.owner
+
+ val parentTrees = typer.typedParentTypes(templ)
+
+ val pending = mutable.ListBuffer[AbsTypeError]()
+ parentTrees foreach { tpt =>
+ val ptpe = tpt.tpe
+ if(!ptpe.isError) {
+ val psym = ptpe.typeSymbol
+ val sameSourceFile = context.unit.source.file == psym.sourceFile
+
+ if (psym.isSealed && !phase.erasedTypes)
+ if (sameSourceFile)
+ psym addChild context.owner
+ else
+ pending += ParentSealedInheritanceError(tpt, psym)
+ if (psym.isLocalToBlock && !phase.erasedTypes)
+ psym addChild context.owner
+ }
+ }
+ pending.foreach(ErrorUtils.issueTypeError)
+
def checkParent(tpt: Tree): Type = {
if (tpt.tpe.isError) AnyRefTpe
else tpt.tpe
}
- val parents = typer.typedParentTypes(templ) map checkParent
+ val parents = parentTrees map checkParent
enterSelf(templ.self)
@@ -1827,6 +1848,12 @@ trait Namers extends MethodSynthesis {
abstract class TypeCompleter extends LazyType {
val tree: Tree
+ override def forceDirectSuperclasses: Unit = {
+ tree.foreach {
+ case dt: DefTree => global.withPropagateCyclicReferences(Option(dt.symbol).map(_.maybeInitialize))
+ case _ =>
+ }
+ }
}
def mkTypeCompleter(t: Tree)(c: Symbol => Unit) = new LockingTypeCompleter with FlagAgnosticCompleter {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index de72d9feed..ec676c30a5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1678,7 +1678,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
supertpts mapConserve (tpt => checkNoEscaping.privates(context.owner, tpt))
}
catch {
- case ex: TypeError =>
+ case ex: TypeError if !global.propagateCyclicReferences =>
// fallback in case of cyclic errors
// @H none of the tests enter here but I couldn't rule it out
// upd. @E when a definition inherits itself, we end up here
@@ -1739,13 +1739,6 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
context.deprecationWarning(parent.pos, psym, report, version)
}
- if (psym.isSealed && !phase.erasedTypes)
- if (sameSourceFile)
- psym addChild context.owner
- else
- pending += ParentSealedInheritanceError(parent, psym)
- if (psym.isLocalToBlock && !phase.erasedTypes)
- psym addChild context.owner
val parentTypeOfThis = parent.tpe.dealias.typeOfThis
if (!(selfType <:< parentTypeOfThis) &&
@@ -5554,6 +5547,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
}
try runTyper() catch {
+ case ex: CyclicReference if global.propagateCyclicReferences =>
+ throw ex
case ex: TypeError =>
tree.clearType()
// The only problematic case are (recoverable) cyclic reference errors which can pop up almost anywhere.