diff options
author | Lukas Rytz <lukas.rytz@epfl.ch> | 2010-08-27 08:54:49 +0000 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@epfl.ch> | 2010-08-27 08:54:49 +0000 |
commit | 799a2b0e28ba78f607fb729bb350f6e3733c4845 (patch) | |
tree | f8e80567b8e9969b911de2c72ba3722a3a0825b7 | |
parent | d20380ea9a6a36f227ff8d53f8fdb616067ccde8 (diff) | |
download | scala-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
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 } +} |