From 7206df0374add1bcf73e15f61a024852463f6fc9 Mon Sep 17 00:00:00 2001 From: Paul Phillips Date: Fri, 31 Aug 2012 08:43:33 -0700 Subject: Don't synthesize trees with overloaded calls. Finding call sites where we would generate (and get away with) an overloaded constructor call after overloading resolution is already done. --- src/compiler/scala/tools/nsc/ast/TreeGen.scala | 5 ++++- src/compiler/scala/tools/nsc/transform/Constructors.scala | 2 +- src/reflect/scala/reflect/internal/Definitions.scala | 1 + src/reflect/scala/reflect/internal/Trees.scala | 8 ++++++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala index 3ccd8ec4ae..0e65bfca6d 100644 --- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala +++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala @@ -52,7 +52,10 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL { } // wrap the given expression in a SoftReference so it can be gc-ed - def mkSoftRef(expr: Tree): Tree = atPos(expr.pos)(New(SoftReferenceClass.tpe, expr)) + def mkSoftRef(expr: Tree): Tree = atPos(expr.pos) { + val constructor = SoftReferenceClass.info.nonPrivateMember(nme.CONSTRUCTOR).suchThat(_.paramss.flatten.size == 1) + NewFromConstructor(constructor, List(expr)) + } // annotate the expression with @unchecked def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) { diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala index afc109c47a..283b923bc5 100644 --- a/src/compiler/scala/tools/nsc/transform/Constructors.scala +++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala @@ -129,7 +129,7 @@ abstract class Constructors extends Transform with ast.TreeDSL { if (from.name != nme.OUTER) result else localTyper.typedPos(to.pos) { - IF (from OBJ_EQ NULL) THEN Throw(NullPointerExceptionClass.tpe) ELSE result + IF (from OBJ_EQ NULL) THEN Throw(NewFromConstructor(NPEConstructor, Nil)) ELSE result } } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index a8e9fd3586..d14a9e50a6 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -282,6 +282,7 @@ trait Definitions extends api.StandardDefinitions { lazy val MatchErrorClass = requiredClass[MatchError] lazy val NonLocalReturnControlClass = requiredClass[scala.runtime.NonLocalReturnControl[_]] lazy val NullPointerExceptionClass = getClassByName(sn.NPException) + lazy val NPEConstructor = getMemberMethod(NullPointerExceptionClass, nme.CONSTRUCTOR) suchThat (_.paramss.flatten.isEmpty) lazy val ThrowableClass = getClassByName(sn.Throwable) lazy val UninitializedErrorClass = requiredClass[UninitializedFieldError] diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 0180ed4c4f..2ba6c187b7 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -400,6 +400,14 @@ trait Trees extends api.Trees { self: SymbolTable => def ApplyConstructor(tpt: Tree, args: List[Tree]) = Apply(Select(New(tpt), nme.CONSTRUCTOR), args) + def NewFromConstructor(constructor: Symbol, args: List[Tree]) = { + assert(constructor.isConstructor, constructor) + val instance = New(TypeTree(constructor.owner.tpe)) + val init = Select(instance, nme.CONSTRUCTOR) setSymbol constructor + + Apply(init, args) + } + case class ApplyDynamic(qual: Tree, args: List[Tree]) extends SymTree with TermTree with ApplyDynamicApi object ApplyDynamic extends ApplyDynamicExtractor -- cgit v1.2.3