From 2c5890b3a7aa227643fde86ba72820a8016bc453 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 13 Jul 2012 12:31:14 +0200 Subject: SI-5956 trigger copy generation with correct namer the call to `addCopyMethod` passes `templateNamer`, which is supposed to be the namer of the case class template. with two classes of the same name, `addCopyMethod` was triggered in the wrong template. --- .../scala/tools/nsc/typechecker/Namers.scala | 8 +++++--- test/files/neg/t1286.check | 6 +----- test/files/neg/t5956.check | 20 ++++++++++++++++++++ test/files/neg/t5956.scala | 2 ++ 4 files changed, 28 insertions(+), 8 deletions(-) create mode 100644 test/files/neg/t5956.check create mode 100644 test/files/neg/t5956.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index 9580cd5676..48fd6ba928 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -835,13 +835,15 @@ trait Namers extends MethodSynthesis { // add the copy method to case classes; this needs to be done here, not in SyntheticMethods, because // the namer phase must traverse this copy method to create default getters for its parameters. - // here, clazz is the ClassSymbol of the case class (not the module). - if (clazz.isClass && !clazz.hasModuleFlag) { + // here, clazz is the ClassSymbol of the case class (not the module). (!clazz.hasModuleFlag) excludes + // the moduleClass symbol of the companion object when the companion is a "case object". + if (clazz.isCaseClass && !clazz.hasModuleFlag) { val modClass = companionSymbolOf(clazz, context).moduleClass modClass.attachments.get[ClassForCaseCompanionAttachment] foreach { cma => val cdef = cma.caseClass def hasCopy(decls: Scope) = (decls lookup nme.copy) != NoSymbol - if (cdef.mods.isCase && !hasCopy(decls) && + // SI-5956 needs (cdef.symbol == clazz): there can be multiple class symbols with the same name + if (cdef.symbol == clazz && !hasCopy(decls) && !parents.exists(p => hasCopy(p.typeSymbol.info.decls)) && !parents.flatMap(_.baseClasses).distinct.exists(bc => hasCopy(bc.info.decls))) addCopyMethod(cdef, templateNamer) diff --git a/test/files/neg/t1286.check b/test/files/neg/t1286.check index c937fb9cf1..912709613c 100644 --- a/test/files/neg/t1286.check +++ b/test/files/neg/t1286.check @@ -1,9 +1,5 @@ -a.scala:1: error: Companions 'object Foo' and 'trait Foo' must be defined in same file: - Found in t1286/b.scala and t1286/a.scala -trait Foo { - ^ b.scala:1: error: Companions 'trait Foo' and 'object Foo' must be defined in same file: Found in t1286/a.scala and t1286/b.scala object Foo extends Foo { ^ -two errors found +one error found diff --git a/test/files/neg/t5956.check b/test/files/neg/t5956.check new file mode 100644 index 0000000000..6641dac97f --- /dev/null +++ b/test/files/neg/t5956.check @@ -0,0 +1,20 @@ +t5956.scala:1: warning: case classes without a parameter list have been deprecated; +use either case objects or case classes with `()' as parameter list. +object O { case class C[T]; class C } + ^ +t5956.scala:2: warning: case classes without a parameter list have been deprecated; +use either case objects or case classes with `()' as parameter list. +object T { case class C[T]; case class C } + ^ +t5956.scala:2: warning: case classes without a parameter list have been deprecated; +use either case objects or case classes with `()' as parameter list. +object T { case class C[T]; case class C } + ^ +t5956.scala:1: error: C is already defined as case class C +object O { case class C[T]; class C } + ^ +t5956.scala:2: error: C is already defined as case class C +object T { case class C[T]; case class C } + ^ +three warnings found +two errors found diff --git a/test/files/neg/t5956.scala b/test/files/neg/t5956.scala new file mode 100644 index 0000000000..d985fa97a4 --- /dev/null +++ b/test/files/neg/t5956.scala @@ -0,0 +1,2 @@ +object O { case class C[T]; class C } +object T { case class C[T]; case class C } -- cgit v1.2.3