summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-11-02 00:15:06 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-11-02 00:15:06 +0000
commitb80f27780458da880d47392e4ac747d196af355e (patch)
treedb857dc93086a6e11d4af0cef7a8a8506a55ba00
parentb9982a3d3d338d097fbee082c5f6778f6494f5cd (diff)
downloadscala-b80f27780458da880d47392e4ac747d196af355e.tar.gz
scala-b80f27780458da880d47392e4ac747d196af355e.tar.bz2
scala-b80f27780458da880d47392e4ac747d196af355e.zip
Don't crash the compiler for the 'companions in...
Don't crash the compiler for the 'companions in different files' error. This turned out to be pretty bad for the presentation compiler. References #1286. Review by extempore
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala30
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala9
-rw-r--r--test/files/neg/bug1286.check9
4 files changed, 40 insertions, 13 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index f62d221320..34a9dfa5cd 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1185,7 +1185,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
if (res == false) {
val (f1, f2) = (this.sourceFile, that.sourceFile)
if (f1 != null && f2 != null && f1.path != f2.path)
- throw FatalError("Companions '" + this + "' and '" + that + "' must be defined in same file.")
+ throw InvalidCompanions(this, that)
}
res
@@ -2047,6 +2047,9 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
// printStackTrace() // debug
}
+ case class InvalidCompanions(sym1: Symbol, sym2: Symbol)
+ extends Throwable("Companions '" + sym1 + "' and '" + sym2 + "' must be defined in same file")
+
/** A class for type histories */
private sealed case class TypeHistory(var validFrom: Period, info: Type, prev: TypeHistory) {
assert((prev eq null) || phaseId(validFrom) > phaseId(prev.validFrom), this)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index cac788906b..35b34ae5fd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1359,18 +1359,30 @@ trait Namers { self: Analyzer =>
* does not work for classes defined inside methods.
*/
def companionModuleOf(clazz: Symbol, context: Context) = {
- var res = clazz.companionModule
- if (res == NoSymbol)
- res = context.lookup(clazz.name.toTermName, clazz.owner).suchThat(sym =>
- sym.hasFlag(MODULE) && sym.isCoDefinedWith(clazz))
- res
+ try {
+ var res = clazz.companionModule
+ if (res == NoSymbol)
+ res = context.lookup(clazz.name.toTermName, clazz.owner).suchThat(sym =>
+ sym.hasFlag(MODULE) && sym.isCoDefinedWith(clazz))
+ res
+ } catch {
+ case e: InvalidCompanions =>
+ context.error(clazz.pos, e.getMessage)
+ NoSymbol
+ }
}
def companionClassOf(module: Symbol, context: Context) = {
- var res = module.companionClass
- if (res == NoSymbol)
- res = context.lookup(module.name.toTypeName, module.owner).suchThat(_.isCoDefinedWith(module))
- res
+ try {
+ var res = module.companionClass
+ if (res == NoSymbol)
+ res = context.lookup(module.name.toTypeName, module.owner).suchThat(_.isCoDefinedWith(module))
+ res
+ } catch {
+ case e: InvalidCompanions =>
+ context.error(module.pos, e.getMessage)
+ NoSymbol
+ }
}
/** An explanatory note to be added to error messages
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index e0e8efb007..d87cd571d8 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1330,7 +1330,14 @@ trait Typers { self: Analyzer =>
// attributes(mdef)
// initialize all constructors of the linked class: the type completer (Namer.methodSig)
// might add default getters to this object. example: "object T; class T(x: Int = 1)"
- val linkedClass = mdef.symbol.companionClass
+ val linkedClass =
+ try {
+ mdef.symbol.companionClass
+ } catch {
+ case e: InvalidCompanions =>
+ context.error(mdef.symbol.pos, e.getMessage)
+ NoSymbol
+ }
if (linkedClass != NoSymbol)
for (c <- linkedClass.info.decl(nme.CONSTRUCTOR).alternatives)
c.initialize
diff --git a/test/files/neg/bug1286.check b/test/files/neg/bug1286.check
index 9bf63252cc..734964e9cf 100644
--- a/test/files/neg/bug1286.check
+++ b/test/files/neg/bug1286.check
@@ -1,2 +1,7 @@
-error: fatal error: Companions 'object Foo' and 'trait Foo' must be defined in same file.
-one error found
+a.scala:1: error: Companions 'object Foo' and 'trait Foo' must be defined in same file
+trait Foo {
+ ^
+b.scala:1: error: Companions 'trait Foo' and 'object Foo' must be defined in same file
+object Foo extends Foo {
+ ^
+two errors found