Allow SkyValues to be marked not "comparable". Such values are not compared for the purpose of change pruning.

--
MOS_MIGRATED_REVID=108203369
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
index 58753ad..be934a5 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageValue.java
@@ -20,8 +20,8 @@
 import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
 import com.google.devtools.build.lib.packages.Package;
 import com.google.devtools.build.lib.vfs.RootedPath;
+import com.google.devtools.build.skyframe.NotComparableSkyValue;
 import com.google.devtools.build.skyframe.SkyKey;
-import com.google.devtools.build.skyframe.SkyValue;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -31,7 +31,7 @@
  */
 @Immutable
 @ThreadSafe
-public class PackageValue implements SkyValue {
+public class PackageValue implements NotComparableSkyValue {
 
   private final Package pkg;
 
diff --git a/src/main/java/com/google/devtools/build/skyframe/BuildingState.java b/src/main/java/com/google/devtools/build/skyframe/BuildingState.java
index 1f72484..d0d2573 100644
--- a/src/main/java/com/google/devtools/build/skyframe/BuildingState.java
+++ b/src/main/java/com/google/devtools/build/skyframe/BuildingState.java
@@ -300,6 +300,9 @@
    */
   boolean unchangedFromLastBuild(SkyValue newValue) {
     checkFinishedBuildingWhenAboutToSetValue();
+    if (newValue instanceof NotComparableSkyValue) {
+      return false;
+    }
     return getLastBuildValue().equals(newValue) && lastBuildDirectDeps.equals(directDeps);
   }
 
diff --git a/src/main/java/com/google/devtools/build/skyframe/NotComparableSkyValue.java b/src/main/java/com/google/devtools/build/skyframe/NotComparableSkyValue.java
new file mode 100644
index 0000000..5cb211b
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skyframe/NotComparableSkyValue.java
@@ -0,0 +1,18 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.skyframe;
+
+/** A SkyValue which, after a fresh evaluation, can never be equal to its last value. */
+public interface NotComparableSkyValue extends SkyValue {
+}
diff --git a/src/main/java/com/google/devtools/build/skyframe/ValueWithMetadata.java b/src/main/java/com/google/devtools/build/skyframe/ValueWithMetadata.java
index 6eab026..b702433 100644
--- a/src/main/java/com/google/devtools/build/skyframe/ValueWithMetadata.java
+++ b/src/main/java/com/google/devtools/build/skyframe/ValueWithMetadata.java
@@ -60,7 +60,7 @@
     if (errorInfo == null) {
       return transitiveEvents.isEmpty()
           ? value
-          : new ValueWithEvents(value, transitiveEvents);
+          : ValueWithEvents.createValueWithEvents(value, transitiveEvents);
     }
     return new ErrorInfoValue(errorInfo, value, transitiveEvents);
   }
@@ -75,15 +75,24 @@
   public abstract NestedSet<TaggedEvents> getTransitiveEvents();
 
   /** Implementation of {@link ValueWithMetadata} for the value case. */
-  public static final class ValueWithEvents extends ValueWithMetadata {
+  public static class ValueWithEvents extends ValueWithMetadata {
 
     private final NestedSet<TaggedEvents> transitiveEvents;
 
-    public ValueWithEvents(SkyValue value, NestedSet<TaggedEvents> transitiveEvents) {
+    private ValueWithEvents(SkyValue value, NestedSet<TaggedEvents> transitiveEvents) {
       super(Preconditions.checkNotNull(value));
       this.transitiveEvents = Preconditions.checkNotNull(transitiveEvents);
     }
 
+    public static ValueWithEvents createValueWithEvents(SkyValue value,
+            NestedSet<TaggedEvents> transitiveEvents) {
+      if (value instanceof NotComparableSkyValue) {
+        return new NotComparableValueWithEvents(value, transitiveEvents);
+      } else {
+        return new ValueWithEvents(value, transitiveEvents);
+      }
+    }
+
     @Nullable
     @Override
     ErrorInfo getErrorInfo() { return null; }
@@ -124,8 +133,21 @@
     public String toString() { return value.toString(); }
   }
 
-  /** Implementation of {@link ValueWithMetadata} for the error case. */
-  private static final class ErrorInfoValue extends ValueWithMetadata {
+  private static final class NotComparableValueWithEvents extends ValueWithEvents
+          implements NotComparableSkyValue {
+    private NotComparableValueWithEvents(SkyValue value,
+            NestedSet<TaggedEvents> transitiveEvents) {
+      super(value, transitiveEvents);
+    }
+  }
+
+  /**
+   * Implementation of {@link ValueWithMetadata} for the error case.
+   *
+   * ErorInfo does not override equals(), so it may as well be marked NotComparableSkyValue.
+   */
+  private static final class ErrorInfoValue extends ValueWithMetadata
+          implements NotComparableSkyValue {
 
     private final ErrorInfo errorInfo;
     private final NestedSet<TaggedEvents> transitiveEvents;
@@ -198,7 +220,7 @@
     if (value instanceof ValueWithMetadata) {
       return (ValueWithMetadata) value;
     }
-    return new ValueWithEvents(value, NO_EVENTS);
+    return ValueWithEvents.createValueWithEvents(value, NO_EVENTS);
   }
 
   @Nullable