summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@epfl.ch>2010-08-27 08:54:49 +0000
committerLukas Rytz <lukas.rytz@epfl.ch>2010-08-27 08:54:49 +0000
commit799a2b0e28ba78f607fb729bb350f6e3733c4845 (patch)
treef8e80567b8e9969b911de2c72ba3722a3a0825b7
parentd20380ea9a6a36f227ff8d53f8fdb616067ccde8 (diff)
downloadscala-799a2b0e28ba78f607fb729bb350f6e3733c4845.tar.gz
scala-799a2b0e28ba78f607fb729bb350f6e3733c4845.tar.bz2
scala-799a2b0e28ba78f607fb729bb350f6e3733c4845.zip
partial fix for see #3772.
{{{ scala> def g { case class C(); object C; } <console>:5: error: C is already defined as (compiler-generated) case class companion object C def g { case class C(); object C; } ^ }}} review by odersky
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala25
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala19
-rw-r--r--test/files/pos/caseClassInMethod.scala5
4 files changed, 34 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 609dcdc829..8d02a120d3 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1253,6 +1253,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** The class with the same name in the same package as this module or
* case class factory.
+ * Note: does not work for classes owned by methods, see
+ * Namers.companionClassOf
*/
final def companionClass: Symbol = {
if (this != NoSymbol)
@@ -1269,6 +1271,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** The module or case class factory with the same name in the same
* package as this class.
+ * Note: does not work for modules owned by methods, see
+ * Namers.companionModuleOf
*/
final def companionModule: Symbol =
if (this.isClass && !this.isAnonymousClass && !this.isRefinementClass)
@@ -1277,6 +1281,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** For a module its linked class, for a class its linked module or case
* factory otherwise.
+ * Note: does not work for modules owned by methods, see
+ * Namers.companionModuleOf / Namers.companionClassOf
*/
final def companionSymbol: Symbol =
if (isTerm) companionClass
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index cd5de7cb7b..235f067c95 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -288,8 +288,10 @@ trait Namers { self: Analyzer =>
* @return the companion object symbol.
*/
def ensureCompanionObject(tree: ClassDef, creator: => Tree): Symbol = {
- val m: Symbol = context.scope.lookup(tree.name.toTermName).filter(! _.isSourceMethod)
- if (m.isModule && inCurrentScope(m) && currentRun.compiles(m)) m
+ val m = companionModuleOf(tree.symbol, context)
+ // @luc: not sure why "currentRun.compiles(m)" is needed, things breaks
+ // otherwise. documentation welcome.
+ if (m != NoSymbol && currentRun.compiles(m)) m
else enterSyntheticSym(creator)
}
@@ -1364,6 +1366,25 @@ trait Namers { self: Analyzer =>
} else member.accessed
} else member
+ /**
+ * Finds the companion module of a class symbol. Calling .companionModule
+ * 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
+ }
+
+ 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
+ }
+
/** An explanatory note to be added to error messages
* when there's a problem with abstract var defs */
def varNotice(sym: Symbol): String =
diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
index 35bb661377..e649e55c08 100644
--- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
@@ -506,25 +506,6 @@ trait NamesDefaults { self: Analyzer =>
}
/**
- * Finds the companion module of a class symbol. Calling .companionModule
- * 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
- }
-
- 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
- }
-
- /**
* Returns
* - the position of the parameter named `name`
* - optionally, if `name` is @deprecatedName, the new name
diff --git a/test/files/pos/caseClassInMethod.scala b/test/files/pos/caseClassInMethod.scala
new file mode 100644
index 0000000000..958e5dd473
--- /dev/null
+++ b/test/files/pos/caseClassInMethod.scala
@@ -0,0 +1,5 @@
+object t {
+ def f = { object C; case class C(); 1 }
+ // pending: def g = { case class D(x: Int); object D; 2 }
+ def h = { case class E(y: Int = 10); 3 }
+}