From 799a2b0e28ba78f607fb729bb350f6e3733c4845 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 27 Aug 2010 08:54:49 +0000 Subject: partial fix for see #3772. {{{ scala> def g { case class C(); object C; } :5: error: C is already defined as (compiler-generated) case class companion object C def g { case class C(); object C; } ^ }}} review by odersky --- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 6 ++++++ .../scala/tools/nsc/typechecker/Namers.scala | 25 ++++++++++++++++++++-- .../tools/nsc/typechecker/NamesDefaults.scala | 19 ---------------- 3 files changed, 29 insertions(+), 21 deletions(-) (limited to 'src') 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 @@ -505,25 +505,6 @@ trait NamesDefaults { self: Analyzer => (namelessArgs, argPos) } - /** - * 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` -- cgit v1.2.3