diff options
9 files changed, 45 insertions, 29 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 8d70a76c9f..f50dee615b 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -1173,13 +1173,6 @@ trait Symbols { */ def alias: Symbol = NoSymbol - /** For parameter symbols: the method computing its default value, NoSymbol - * for all others - */ - def defaultGetter: Symbol = NoSymbol - def defaultGetter_=(getter: Symbol): Unit = - throw new Error("defaultGetter cannot be set for " + this) - /** For a lazy value, its lazy accessor. NoSymbol for all others */ def lazyAccessor: Symbol = NoSymbol @@ -1670,14 +1663,12 @@ trait Symbols { privateWithin = NoSymbol protected var referenced: Symbol = NoSymbol - protected var defGetter: Symbol = NoSymbol def cloneSymbolImpl(owner: Symbol): Symbol = new TermSymbol(owner, pos, name).copyAttrsFrom(this) def copyAttrsFrom(original: TermSymbol): this.type = { referenced = original.referenced - defGetter = original.defGetter this } @@ -1696,10 +1687,6 @@ trait Symbols { this } - override def defaultGetter = defGetter - override def defaultGetter_=(getter: Symbol): Unit = - defGetter = getter - override def outerSource: Symbol = if (name endsWith nme.OUTER) initialize.referenced else NoSymbol diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala index 290f778827..483f67e066 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala @@ -136,7 +136,6 @@ abstract class Pickler extends SubComponent { if (sym.thisSym.tpeHK != sym.tpeHK) putType(sym.typeOfThis); putSymbol(sym.alias) - putSymbol(sym.defaultGetter) if (!sym.children.isEmpty) { val (locals, globals) = sym.children.toList.partition(_.isLocalClass) val children = @@ -561,8 +560,6 @@ abstract class Pickler extends SubComponent { writeSymInfo(sym) if (sym.isAbstractType) TYPEsym else ALIASsym case sym: TermSymbol => - if (!sym.isModule && sym.defaultGetter != NoSymbol) - writeRef(sym.defaultGetter) writeSymInfo(sym) if (sym.alias != NoSymbol) writeRef(sym.alias) if (sym.isModule) MODULEsym else VALsym @@ -1017,7 +1014,6 @@ abstract class Pickler extends SubComponent { case sym: TermSymbol => print(if (sym.isModule) "MODULEsym " else "VALsym ") printSymInfo(sym) - if (!sym.isModule) printRef(sym.defaultGetter) if (sym.alias != NoSymbol) printRef(sym.alias) case NoType => print("NOtpe") diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala index bd1a13187d..b8fc0ea1d3 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/UnPickler.scala @@ -203,9 +203,9 @@ abstract class UnPickler { case NONEsym => sym = NoSymbol case _ => // symbols that were pickled with Pickler.writeSymInfo - var defaultGetter: Symbol = NoSymbol + var defaultGetter: Symbol = NoSymbol // @deprecated, to be removed for 2.8 final var nameref = readNat() - if (tag == VALsym && isSymbolRef(nameref)) { + if (tag == VALsym && isSymbolRef(nameref)) { // @deprecated, to be removed for 2.8 final defaultGetter = at(nameref, readSymbol) nameref = readNat() } @@ -247,7 +247,6 @@ abstract class UnPickler { sym = if (name == moduleRoot.name && owner == moduleRoot.owner) moduleRoot.resetFlag(MODULE) else if ((flags & METHOD) != 0) owner.newMethod(NoPosition, name) else owner.newValue(NoPosition, name) - sym.defaultGetter = defaultGetter case _ => errorBadSignature("bad symbol tag: " + tag) } diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index c755beb04e..74c57c0fb7 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -319,7 +319,6 @@ trait Namers { self: Analyzer => (param, cparam) <- params.zip(cparams)) { // need to clone the type cparam.tpe??? problem is: we don't have the new owner yet (the new param symbol) param.tpt.setType(subst(cparam.tpe)) - () // @LUC TODO workaround for #1996 } ltype.complete(sym) })) @@ -1033,12 +1032,10 @@ trait Namers { self: Analyzer => } meth.owner.resetFlag(INTERFACE) // there's a concrete member now val default = parentNamer.enterSyntheticSym(defaultTree) - sym.defaultGetter = default } else if (baseHasDefault) { // the parameter does not have a default itself, but the corresponding parameter // in the base class does. sym.setFlag(DEFAULTPARAM) - sym.defaultGetter = baseParams.head.defaultGetter } posCounter += 1 if (overrides) baseParams = baseParams.tail diff --git a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala index 7f8e23e7f7..b41924c3bb 100644 --- a/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala +++ b/src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala @@ -341,14 +341,15 @@ trait NamesDefaults { self: Analyzer => * the argument list (y = "lt") is transformed to (y = "lt", x = foo$default$1()) */ def addDefaults(givenArgs: List[Tree], qual: Option[Tree], targs: List[Tree], - previousArgss: List[List[Tree]], params: List[Symbol], pos: util.Position): (List[Tree], List[Symbol]) = { + previousArgss: List[List[Tree]], params: List[Symbol], + pos: util.Position, context: Context): (List[Tree], List[Symbol]) = { if (givenArgs.length < params.length) { val (missing, positional) = missingParams(givenArgs, params) if (missing forall (_.hasFlag(DEFAULTPARAM))) { val defaultArgs = missing map (p => { var default1 = qual match { - case Some(q) => gen.mkAttributedSelect(q.duplicate, p.defaultGetter) - case None => gen.mkAttributedRef(p.defaultGetter) + case Some(q) => gen.mkAttributedSelect(q.duplicate, defaultGetter(p, context)) + case None => gen.mkAttributedRef(defaultGetter(p, context)) } default1 = if (targs.isEmpty) default1 else TypeApply(default1, targs.map(_.duplicate)) @@ -365,6 +366,38 @@ trait NamesDefaults { self: Analyzer => } /** + * For a parameter with default argument, find the method symbol of + * the default getter. + */ + def defaultGetter(param: Symbol, context: Context) = { + val i = param.owner.paramss.flatten.findIndexOf(p => p.name == param.name) + 1 + if (i > 0) { + if (param.owner.isConstructor) { + val defGetterName = "init$default$"+ i + param.owner.owner.linkedModuleOfClass.info.member(defGetterName) + } else { + val defGetterName = param.owner.name +"$default$"+ i + if (param.owner.owner.isClass) { + param.owner.owner.info.member(defGetterName) + } else { + // the owner of the method is another method. find the default + // getter in the context. + var res: Symbol = NoSymbol + var ctx = context + while(res == NoSymbol && ctx.outer != ctx) { + val s = ctx.scope.lookup(defGetterName) + if (s != NoSymbol && s.owner == param.owner.owner) + res = s + else + ctx = ctx.outer + } + res + } + } + } else NoSymbol + } + + /** * Removes name assignments from args. Additionally, returns an array mapping * argument indicies from call-site-order to definition-site-order. * diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index d8a0d0a166..baa0f9a8be 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -2346,7 +2346,7 @@ trait Typers { self: Analyzer => true case _ => false } - val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos.focus) + val (allArgs, missing) = addDefaults(args, qual, targs, previousArgss, params, fun.pos.focus, context) if (allArgs.length == formals.length) { // useful when a default doesn't match parameter type, e.g. def f[T](x:T="a"); f[Int]() context.diagnostic = "Error occured in an application involving default arguments." :: context.diagnostic diff --git a/test/files/run/names-defaults.check b/test/files/run/names-defaults.check index ac4fb84423..60c7637e3d 100644 --- a/test/files/run/names-defaults.check +++ b/test/files/run/names-defaults.check @@ -120,3 +120,4 @@ klfj1 blublu1 my text List(1, 2) +3 diff --git a/test/files/run/names-defaults.scala b/test/files/run/names-defaults.scala index d751b50148..54a09c14f9 100644 --- a/test/files/run/names-defaults.scala +++ b/test/files/run/names-defaults.scala @@ -256,6 +256,9 @@ object Test extends Application { def test11[T[P]](x: T[T[List[T[X forSome { type X }]]]] = List(1,2)) = x // (cannot call f using the default, List(1,2) doesn't match the param type) + def multinest = { def bar(x: Int = 1) = { def bar(x: Int = 2) = x; bar() + x }; bar() } + println(multinest) + // #2290 def spawn(a: Int, b: => Unit) = { () } diff --git a/test/files/scalap/caseClass/result.test b/test/files/scalap/caseClass/result.test index cabf321a07..a1d0ebe167 100644 --- a/test/files/scalap/caseClass/result.test +++ b/test/files/scalap/caseClass/result.test @@ -2,7 +2,7 @@ case class CaseClass[A >: scala.Nothing <: scala.Seq[scala.Int]](i : A, s : scal val i : A = { /* compiled code */ } val s : scala.Predef.String = { /* compiled code */ } def foo : scala.Int = { /* compiled code */ } - def copy[A >: scala.Nothing <: scala.Seq[scala.Int]]() : CaseClass[A] = { /* compiled code */ } + def copy[A >: scala.Nothing <: scala.Seq[scala.Int]](i : A, s : scala.Predef.String) : CaseClass[A] = { /* compiled code */ } def copy$default$1[A >: scala.Nothing <: scala.Seq[scala.Int]] : A = { /* compiled code */ } def copy$default$2[A >: scala.Nothing <: scala.Seq[scala.Int]] : scala.Predef.String = { /* compiled code */ } override def hashCode() : scala.Int = { /* compiled code */ } @@ -12,4 +12,4 @@ case class CaseClass[A >: scala.Nothing <: scala.Seq[scala.Int]](i : A, s : scal override def productArity : scala.Int = { /* compiled code */ } override def productElement(x$1 : scala.Int) : scala.Any = { /* compiled code */ } override def canEqual(x$1 : scala.Any) : scala.Boolean = { /* compiled code */ } -}
\ No newline at end of file +} |