diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala | 21 | ||||
-rw-r--r-- | test/files/neg/bug1183.check | 17 | ||||
-rw-r--r-- | test/files/neg/bug1183.scala | 38 | ||||
-rw-r--r-- | test/files/pos/bug1189.scala | 8 |
5 files changed, 85 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index e2302a509d..27458ad145 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -791,7 +791,7 @@ trait Symbols { else NoSymbol /** For a module class its linked class, for a plain class - * the module class of itys linked module. + * the module class of its linked module. */ final def linkedClassOfClass: Symbol = if (isModuleClass) linkedClassOfModule else linkedModuleOfClass.moduleClass diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala index 32e2a136d2..40f6b37649 100644 --- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala +++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala @@ -67,8 +67,26 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT tree } + /** Check that a class and its companion object to not both define + * a class or module with same name + */ + private def checkCompanionNameClashes(sym: Symbol) = + if (!sym.owner.isModuleClass) { + val linked = sym.owner.linkedClassOfClass + if (linked != NoSymbol) { + var other = linked.info.decl(sym.name.toTypeName).filter(_.isClass) + if (other == NoSymbol) + other = linked.info.decl(sym.name.toTermName).filter(_.isModule) + if (other != NoSymbol) + unit.error(sym.pos, "name clash: "+sym.owner+" defines "+sym+ + "\nand its companion "+sym.owner.linkedModuleOfClass+" also defines "+ + other) + } + } + override def transform(tree: Tree): Tree = tree match { case ClassDef(_, _, _, _) => + checkCompanionNameClashes(tree.symbol) val decls = tree.symbol.info.decls for (val sym <- decls.toList) { if (sym.privateWithin.isClass && !sym.privateWithin.isModuleClass && @@ -79,6 +97,9 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT } } super.transform(tree) + case ModuleDef(_, _, _) => + checkCompanionNameClashes(tree.symbol) + super.transform(tree) case Template(parents, self, body) => val ownAccDefs = new ListBuffer[Tree]; accDefs = (currentOwner, ownAccDefs) :: accDefs; diff --git a/test/files/neg/bug1183.check b/test/files/neg/bug1183.check new file mode 100644 index 0000000000..9b42dccb8d --- /dev/null +++ b/test/files/neg/bug1183.check @@ -0,0 +1,17 @@ +bug1183.scala:10: error: name clash: class Foo defines object Baz + and its companion module object Foo defines class Baz + object Baz + ^ +bug1183.scala:11: error: name clash: class Foo defines class Bam + and its companion module object Foo defines object Bam + class Bam + ^ +bug1183.scala:12: error: name clash: class Foo defines object Bar + and its companion module object Foo defines class Bar + object Bar + ^ +bug1183.scala:13: error: name clash: class Foo defines class Bar + and its companion module object Foo defines class Bar + case class Bar(i:Int) + ^ +four errors found diff --git a/test/files/neg/bug1183.scala b/test/files/neg/bug1183.scala new file mode 100644 index 0000000000..a845126488 --- /dev/null +++ b/test/files/neg/bug1183.scala @@ -0,0 +1,38 @@ +import scala.testing.SUnit._ + +object Test extends TestConsoleMain { + + def suite = new TestSuite( + new Test717 + ) + + class Foo(j:Int) { + object Baz + class Bam + object Bar + case class Bar(i:Int) + } + + + class Test717 extends TestCase("#717 test path of case classes") { + val foo1 = new Foo(1) + + override def runTest() = { + val res = (foo1.Bar(2):Any) match { + case foo1.Bar(2) => true // (1) + } + assertTrue("ok", res); + } + } + + // (2) + object Foo { + class Bar(val x : String) + class Baz + object Bam + object Bar + + def unapply(s : String) : Option[Bar] = Some(new Bar(s)) + } + +} diff --git a/test/files/pos/bug1189.scala b/test/files/pos/bug1189.scala new file mode 100644 index 0000000000..97d2e4488c --- /dev/null +++ b/test/files/pos/bug1189.scala @@ -0,0 +1,8 @@ +object test extends Application { + case class Cell[T](x: T) + type U = Cell[T1] forSome { type T1 } + def f[T](x: Any): U = x match { case y: Cell[_] => y } + + var x: U = Cell(1) + println(x) +} |