From a72aa94f09b95342465d9d9d31d0fdff2ef63159 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sat, 26 Jan 2013 15:04:40 +0100 Subject: SI-7018 Fix memory leak in Attachments. Makes NonEmptyAttachments a top level class so that it doesn't accidentally accumulate history via the $outer field. No test is included because I think the fix is self evident. --- src/reflect/scala/reflect/macros/Attachments.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/reflect/scala/reflect/macros/Attachments.scala b/src/reflect/scala/reflect/macros/Attachments.scala index a77cebf415..eeb87fafcc 100644 --- a/src/reflect/scala/reflect/macros/Attachments.scala +++ b/src/reflect/scala/reflect/macros/Attachments.scala @@ -44,17 +44,19 @@ abstract class Attachments { self => * Replaces an existing payload of the same type, if exists. */ def update[T: ClassTag](attachment: T): Attachments { type Pos = self.Pos } = - new NonemptyAttachments(this.pos, remove[T].all + attachment) + new NonemptyAttachments[Pos](this.pos, remove[T].all + attachment) /** Creates a copy of this attachment with the payload of the given class type `T` removed. */ def remove[T: ClassTag]: Attachments { type Pos = self.Pos } = { val newAll = all filterNot matchesTag[T] if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }] - else new NonemptyAttachments(this.pos, newAll) + else new NonemptyAttachments[Pos](this.pos, newAll) } +} - private class NonemptyAttachments(override val pos: Pos, override val all: Set[Any]) extends Attachments { - type Pos = self.Pos - def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all) - } +// SI-7018: This used to be an inner class of `Attachments`, but that led to a memory leak in the +// IDE via $outer pointers. +private final class NonemptyAttachments[P >: Null](override val pos: P, override val all: Set[Any]) extends Attachments { + type Pos = P + def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all) } -- cgit v1.2.3