@@ -36,6 +36,7 @@ import Flags.FlagSet
3636import language .implicitConversions
3737import scala .util .hashing .{ MurmurHash3 => hashing }
3838import config .Printers .{core , typr , cyclicErrors }
39+ import java .lang .ref .WeakReference
3940
4041object Types {
4142
@@ -3175,12 +3176,18 @@ object Types {
31753176 final class TypeVar (val origin : TypeParamRef , creatorState : TyperState , val bindingTree : untpd.Tree , val owner : Symbol ) extends CachedProxyType with ValueType {
31763177
31773178 /** The permanent instance type of the variable, or NoType is none is given yet */
3178- private [core] var inst : Type = NoType
3179+ private [this ] var myInst : Type = NoType
3180+
3181+ private [core] def inst = myInst
3182+ private [core] def inst_= (tp : Type ) = {
3183+ myInst = tp
3184+ if (tp.exists) owningState = null // no longer needed; null out to avoid a memory leak
3185+ }
31793186
31803187 /** The state owning the variable. This is at first `creatorState`, but it can
31813188 * be changed to an enclosing state on a commit.
31823189 */
3183- private [core] var owningState = creatorState
3190+ private [core] var owningState = new WeakReference ( creatorState)
31843191
31853192 /** The instance type of this variable, or NoType if the variable is currently
31863193 * uninstantiated
@@ -3198,7 +3205,7 @@ object Types {
31983205 private def instantiateWith (tp : Type )(implicit ctx : Context ): Type = {
31993206 assert(tp ne this , s " self instantiation of ${tp.show}, constraint = ${ctx.typerState.constraint.show}" )
32003207 typr.println(s " instantiating ${this .show} with ${tp.show}" )
3201- if ((ctx.typerState eq owningState) && ! ctx.typeComparer.subtypeCheckInProgress)
3208+ if ((ctx.typerState eq owningState.get ) && ! ctx.typeComparer.subtypeCheckInProgress)
32023209 inst = tp
32033210 ctx.typerState.constraint = ctx.typerState.constraint.replace(origin, tp)
32043211 tp
@@ -3546,11 +3553,24 @@ object Types {
35463553 */
35473554 abstract class FlexType extends UncachedGroundType with ValueType
35483555
3549- class ErrorType (_msg : => Message ) extends FlexType {
3550- def msg = _msg
3556+ class ErrorType private [Types ] () extends FlexType {
3557+ def msg (implicit ctx : Context ): Message =
3558+ ctx.errorTypeMsg.get(this ) match {
3559+ case Some (msgFun) => msgFun()
3560+ case None => " error message from previous run no longer available"
3561+ }
3562+ }
3563+ object ErrorType {
3564+ def apply (msg : => Message )(implicit ctx : Context ): ErrorType = {
3565+ val et = new ErrorType
3566+ ctx.base.errorTypeMsg(et) = () => msg
3567+ et
3568+ }
35513569 }
35523570
3553- object UnspecifiedErrorType extends ErrorType (" unspecified error" )
3571+ object UnspecifiedErrorType extends ErrorType () {
3572+ override def msg (implicit ctx : Context ): Message = " unspecified error"
3573+ }
35543574
35553575 /* Type used to track Select nodes that could not resolve a member and their qualifier is a scala.Dynamic. */
35563576 object TryDynamicCallType extends FlexType
0 commit comments