summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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