Add type assertion that TreeFileArtifact's parentTreeArtifact member is a
SpecialArtifact.

PiperOrigin-RevId: 184539696
diff --git a/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java b/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java
index 9e4b938..085415cf 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/CustomCommandLineTest.java
@@ -899,8 +899,8 @@
 
   @Test
   public void testTreeFileArtifactExecPathArgs() {
-    Artifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1");
-    Artifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2");
+    SpecialArtifact treeArtifactOne = createTreeArtifact("myArtifact/treeArtifact1");
+    SpecialArtifact treeArtifactTwo = createTreeArtifact("myArtifact/treeArtifact2");
 
     CustomCommandLine commandLineTemplate =
         builder()
@@ -981,7 +981,7 @@
     }
   }
 
-  private Artifact createTreeArtifact(String rootRelativePath) {
+  private SpecialArtifact createTreeArtifact(String rootRelativePath) {
     PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         rootDir.getRoot().getRelative(relpath),
@@ -992,7 +992,7 @@
   }
 
   private TreeFileArtifact createTreeFileArtifact(
-      Artifact inputTreeArtifact, String parentRelativePath) {
+      SpecialArtifact inputTreeArtifact, String parentRelativePath) {
     return ActionInputHelper.treeFileArtifact(
         inputTreeArtifact,
         PathFragment.create(parentRelativePath));
diff --git a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
index 4792caf..74af54a 100644
--- a/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/actions/util/ActionsTestUtil.java
@@ -40,6 +40,7 @@
 import com.google.devtools.build.lib.actions.ActionResult;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
 import com.google.devtools.build.lib.actions.ArtifactResolver;
@@ -597,7 +598,7 @@
   }
 
   public static SpawnActionTemplate createDummySpawnActionTemplate(
-      Artifact inputTreeArtifact, Artifact outputTreeArtifact) {
+      SpecialArtifact inputTreeArtifact, SpecialArtifact outputTreeArtifact) {
     return new SpawnActionTemplate.Builder(inputTreeArtifact, outputTreeArtifact)
         .setCommandLineTemplate(CustomCommandLine.builder().build())
         .setExecutable(PathFragment.create("bin/executable"))
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java
index 5f85b94..4c9d2dd 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/ParamFileWriteActionTest.java
@@ -52,7 +52,7 @@
 public class ParamFileWriteActionTest extends BuildViewTestCase {
   private ArtifactRoot rootDir;
   private Artifact outputArtifact;
-  private Artifact treeArtifact;
+  private SpecialArtifact treeArtifact;
 
   @Before
   public void createArtifacts() throws Exception  {
@@ -108,7 +108,7 @@
                 + "out/artifact/myTreeFileArtifact/artifacts/treeFileArtifact2");
   }
 
-  private Artifact createTreeArtifact(String rootRelativePath) {
+  private SpecialArtifact createTreeArtifact(String rootRelativePath) {
     PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         rootDir.getRoot().getRelative(relpath),
@@ -119,7 +119,7 @@
   }
 
   private TreeFileArtifact createTreeFileArtifact(
-      Artifact inputTreeArtifact, String parentRelativePath) {
+      SpecialArtifact inputTreeArtifact, String parentRelativePath) {
     return ActionInputHelper.treeFileArtifact(
         inputTreeArtifact,
         PathFragment.create(parentRelativePath));
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java
index a22868b..345aa97 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/PopulateTreeArtifactActionTest.java
@@ -266,8 +266,8 @@
   public void testComputeKey() throws Exception {
     final Artifact archiveA = getSourceArtifact("myArchiveA.zip");
     final Artifact archiveB = getSourceArtifact("myArchiveB.zip");
-    final Artifact treeArtifactToPopulateA = createTreeArtifact("testA/archive_member");
-    final Artifact treeArtifactToPopulateB = createTreeArtifact("testB/archive_member");
+    final SpecialArtifact treeArtifactToPopulateA = createTreeArtifact("testA/archive_member");
+    final SpecialArtifact treeArtifactToPopulateB = createTreeArtifact("testB/archive_member");
     final Artifact archiveManifestA = getSourceArtifact("archiveManifestA.txt");
     final Artifact archiveManifestB = getSourceArtifact("archiveManifestB.txt");
     final FilesToRunProvider zipperA = FilesToRunProvider.fromSingleExecutableArtifact(
@@ -282,7 +282,7 @@
           public Action generate(ImmutableSet<KeyAttributes> attributesToFlip) {
             Artifact archive =
                 attributesToFlip.contains(KeyAttributes.ARCHIVE) ? archiveA : archiveB;
-            Artifact treeArtifactToPopulate =
+            SpecialArtifact treeArtifactToPopulate =
                 attributesToFlip.contains(KeyAttributes.TREE_ARTIFACT)
                     ? treeArtifactToPopulateA
                     : treeArtifactToPopulateB;
@@ -306,7 +306,7 @@
 
   private PopulateTreeArtifactAction createPopulateTreeArtifactAction() throws Exception {
     Artifact archive = getSourceArtifact("myArchive.zip");
-    Artifact treeArtifactToPopulate = createTreeArtifact("test/archive_member");
+    SpecialArtifact treeArtifactToPopulate = createTreeArtifact("test/archive_member");
     Artifact archiveManifest = getSourceArtifact("archiveManifest.txt");
     FilesToRunProvider unzip = FilesToRunProvider.fromSingleExecutableArtifact(
         getSourceArtifact("unzipBinary"));
@@ -343,7 +343,7 @@
         null);
   }
 
-  private Artifact createTreeArtifact(String rootRelativePath) {
+  private SpecialArtifact createTreeArtifact(String rootRelativePath) {
     PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         root.getRoot().getRelative(relpath),
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java
index 3001b3b..ad03fe7 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/actions/SpawnActionTemplateTest.java
@@ -66,8 +66,8 @@
 
   @Test
   public void testCommonToolsAndInputs() {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
     Artifact commonInput = createDerivedArtifact("common/input");
     Artifact commonTool = createDerivedArtifact("common/tool");
     Artifact executable = createDerivedArtifact("bin/cp");
@@ -90,8 +90,8 @@
 
   @Test
   public void testBuilder_outputPathMapperRequired() {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
     SpawnActionTemplate.Builder builder = builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
         .setExecutable(PathFragment.create("/bin/cp"))
@@ -107,8 +107,8 @@
 
   @Test
   public void testBuilder_executableRequired() {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
     SpawnActionTemplate.Builder builder = builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
         .setOutputPathMapper(IDENTITY_MAPPER)
@@ -124,8 +124,8 @@
 
   @Test
   public void testBuilder_commandlineTemplateRequired() {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
     SpawnActionTemplate.Builder builder = builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
         .setOutputPathMapper(IDENTITY_MAPPER)
@@ -141,8 +141,8 @@
   @Test
   public void testExpandedAction_inputAndOutputTreeFileArtifacts() throws Exception {
     SpawnActionTemplate actionTemplate = createSimpleSpawnActionTemplate();
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
 
     Iterable<TreeFileArtifact> inputTreeFileArtifacts =
         createInputTreeFileArtifacts(inputTreeArtifact);
@@ -167,8 +167,8 @@
 
   @Test
   public void testExpandedAction_commonToolsAndInputs() throws Exception {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
     Artifact commonInput = createDerivedArtifact("common/input");
     Artifact commonTool = createDerivedArtifact("common/tool");
     Artifact executable = createDerivedArtifact("bin/cp");
@@ -201,8 +201,8 @@
   @Test
   public void testExpandedAction_arguments() throws Exception {
     SpawnActionTemplate actionTemplate = createSimpleSpawnActionTemplate();
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
 
     Iterable<TreeFileArtifact> inputTreeFileArtifacts =
         createInputTreeFileArtifacts(inputTreeArtifact);
@@ -228,7 +228,7 @@
   @Test
   public void testExpandedAction_executionInfoAndEnvironment() throws Exception {
     SpawnActionTemplate actionTemplate = createSimpleSpawnActionTemplate();
-    Artifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
     Iterable<TreeFileArtifact> inputTreeFileArtifacts =
         createInputTreeFileArtifacts(inputTreeArtifact);
 
@@ -247,8 +247,8 @@
 
   @Test
   public void testExpandedAction_illegalOutputPath() throws Exception {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
     Iterable<TreeFileArtifact> inputTreeFileArtifacts =
         createInputTreeFileArtifacts(inputTreeArtifact);
 
@@ -294,14 +294,14 @@
     }
   }
 
-  private SpawnActionTemplate.Builder builder(Artifact inputTreeArtifact,
-      Artifact outputTreeArtifact) {
+  private SpawnActionTemplate.Builder builder(
+      SpecialArtifact inputTreeArtifact, SpecialArtifact outputTreeArtifact) {
     return new SpawnActionTemplate.Builder(inputTreeArtifact, outputTreeArtifact);
   }
 
   private SpawnActionTemplate createSimpleSpawnActionTemplate() {
-    Artifact inputTreeArtifact = createInputTreeArtifact();
-    Artifact outputTreeArtifact = createOutputTreeArtifact();
+    SpecialArtifact inputTreeArtifact = createInputTreeArtifact();
+    SpecialArtifact outputTreeArtifact = createOutputTreeArtifact();
 
     return builder(inputTreeArtifact, outputTreeArtifact)
         .setExecutionInfo(ImmutableMap.<String, String>of("local", ""))
@@ -314,15 +314,15 @@
         .build(ActionsTestUtil.NULL_ACTION_OWNER);
   }
 
-  private Artifact createInputTreeArtifact() {
+  private SpecialArtifact createInputTreeArtifact() {
     return createTreeArtifact("my/inputTree");
   }
 
-  private Artifact createOutputTreeArtifact() {
+  private SpecialArtifact createOutputTreeArtifact() {
     return createTreeArtifact("my/outputTree");
   }
 
-  private Artifact createTreeArtifact(String rootRelativePath) {
+  private SpecialArtifact createTreeArtifact(String rootRelativePath) {
     PathFragment relpath = PathFragment.create(rootRelativePath);
     return new SpecialArtifact(
         root.getRoot().getRelative(relpath),
@@ -344,7 +344,8 @@
         .build();
   }
 
-  private Iterable<TreeFileArtifact> createInputTreeFileArtifacts(Artifact inputTreeArtifact) {
+  private Iterable<TreeFileArtifact> createInputTreeFileArtifacts(
+      SpecialArtifact inputTreeArtifact) {
     return ActionInputHelper.asTreeFileArtifacts(
         inputTreeArtifact,
         ImmutableList.of(
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
index 2f7ad5b..dc15b84 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestUtil.java
@@ -27,6 +27,7 @@
 import com.google.devtools.build.lib.actions.ActionOwner;
 import com.google.devtools.build.lib.actions.ActionResult;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.ArtifactFactory;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
 import com.google.devtools.build.lib.actions.ArtifactRoot;
@@ -130,7 +131,7 @@
     }
 
     @Override
-    public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
+    public SpecialArtifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
@@ -331,7 +332,7 @@
     }
 
     @Override
-    public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
+    public SpecialArtifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       return null;
     }
 
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 38738a2..8d89ee0 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -35,6 +35,7 @@
 import com.google.devtools.build.lib.actions.ActionInput;
 import com.google.devtools.build.lib.actions.ActionKeyContext;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
 import com.google.devtools.build.lib.actions.ArtifactRoot;
 import com.google.devtools.build.lib.actions.CommandLineExpansionException;
@@ -1714,7 +1715,7 @@
     }
 
     @Override
-    public Artifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
+    public SpecialArtifact getTreeArtifact(PathFragment rootRelativePath, ArtifactRoot root) {
       throw new UnsupportedOperationException();
     }
 
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
index a6bda43..db56bd5 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java
@@ -668,7 +668,7 @@
     assertError("the need whole archive flag must be false for static links", builder);
   }
 
-  private Artifact createTreeArtifact(String name) {
+  private SpecialArtifact createTreeArtifact(String name) {
     FileSystem fs = scratch.getFileSystem();
     Path execRoot = fs.getPath(TestUtils.tmpDir());
     PathFragment execPath = PathFragment.create("out").getRelative(name);
@@ -691,7 +691,7 @@
 
   @Test
   public void testLinksTreeArtifactLibraries() throws Exception {
-    Artifact testTreeArtifact = createTreeArtifact("library_directory");
+    SpecialArtifact testTreeArtifact = createTreeArtifact("library_directory");
 
     TreeFileArtifact library0 = ActionInputHelper.treeFileArtifact(testTreeArtifact, "library0.o");
     TreeFileArtifact library1 = ActionInputHelper.treeFileArtifact(testTreeArtifact, "library1.o");
@@ -738,7 +738,7 @@
             LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY,
             LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY);
 
-    Artifact testTreeArtifact = createTreeArtifact("library_directory");
+    SpecialArtifact testTreeArtifact = createTreeArtifact("library_directory");
 
     TreeFileArtifact library0 = ActionInputHelper.treeFileArtifact(testTreeArtifact, "library0.o");
     TreeFileArtifact library1 = ActionInputHelper.treeFileArtifact(testTreeArtifact, "library1.o");
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
index e3937d4..a2df8b5 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java
@@ -28,6 +28,7 @@
 import com.google.devtools.build.lib.actions.ActionInputHelper;
 import com.google.devtools.build.lib.actions.ActionInputPrefetcher;
 import com.google.devtools.build.lib.actions.Artifact;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact;
 import com.google.devtools.build.lib.actions.ArtifactOwner;
 import com.google.devtools.build.lib.actions.CommandAction;
@@ -936,9 +937,9 @@
     // Therefore we need to fake some files inside them to test the action template in this
     // analysis-time test.
     TreeFileArtifact oneSourceFileFromGenJar =
-        ActionInputHelper.treeFileArtifact(sourceFilesFromGenJar, "children1.m");
+        ActionInputHelper.treeFileArtifact((SpecialArtifact) sourceFilesFromGenJar, "children1.m");
     TreeFileArtifact oneObjFileFromGenJar =
-        ActionInputHelper.treeFileArtifact(objectFilesFromGenJar, "children1.o");
+        ActionInputHelper.treeFileArtifact((SpecialArtifact) objectFilesFromGenJar, "children1.o");
     Iterable<CommandAction> compileActions =
         getActionsForInputsOfGeneratingActionTemplate(
             objectFilesFromGenJar, oneSourceFileFromGenJar);
diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java
index 85e4ff5..09cb47d 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java
@@ -17,6 +17,7 @@
 import com.google.devtools.build.lib.actions.ActionInputHelper;
 import com.google.devtools.build.lib.actions.Artifact;
 import com.google.devtools.build.lib.actions.Artifact.ArtifactExpander;
+import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact;
 import com.google.devtools.build.lib.analysis.ConfiguredTarget;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
 import com.google.devtools.build.lib.cmdline.Label;
@@ -34,8 +35,8 @@
       new ArtifactExpander() {
         @Override
         public void expand(Artifact artifact, Collection<? super Artifact> output) {
-          output.add(ActionInputHelper.treeFileArtifact(artifact, "children1"));
-          output.add(ActionInputHelper.treeFileArtifact(artifact, "children2"));
+          output.add(ActionInputHelper.treeFileArtifact((SpecialArtifact) artifact, "children1"));
+          output.add(ActionInputHelper.treeFileArtifact((SpecialArtifact) artifact, "children2"));
         }
       };
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java
index b6a834e..147b8b2 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionTemplateExpansionFunctionTest.java
@@ -96,9 +96,9 @@
 
   @Test
   public void testActionTemplateExpansionFunction() throws Exception {
-    Artifact inputTreeArtifact = createAndPopulateTreeArtifact(
-        "inputTreeArtifact", "child0", "child1", "child2");
-    Artifact outputTreeArtifact = createTreeArtifact("outputTreeArtifact");
+    SpecialArtifact inputTreeArtifact =
+        createAndPopulateTreeArtifact("inputTreeArtifact", "child0", "child1", "child2");
+    SpecialArtifact outputTreeArtifact = createTreeArtifact("outputTreeArtifact");
 
     SpawnActionTemplate spawnActionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         inputTreeArtifact, outputTreeArtifact);
@@ -120,10 +120,9 @@
 
   @Test
   public void testThrowsOnActionConflict() throws Exception {
-    Artifact inputTreeArtifact = createAndPopulateTreeArtifact(
-        "inputTreeArtifact", "child0", "child1", "child2");
-    Artifact outputTreeArtifact = createTreeArtifact("outputTreeArtifact");
-
+    SpecialArtifact inputTreeArtifact =
+        createAndPopulateTreeArtifact("inputTreeArtifact", "child0", "child1", "child2");
+    SpecialArtifact outputTreeArtifact = createTreeArtifact("outputTreeArtifact");
 
     OutputPathMapper mapper = new OutputPathMapper() {
       @Override
@@ -148,9 +147,9 @@
 
   @Test
   public void testThrowsOnArtifactPrefixConflict() throws Exception {
-    Artifact inputTreeArtifact = createAndPopulateTreeArtifact(
-        "inputTreeArtifact", "child0", "child1", "child2");
-    Artifact outputTreeArtifact = createTreeArtifact("outputTreeArtifact");
+    SpecialArtifact inputTreeArtifact =
+        createAndPopulateTreeArtifact("inputTreeArtifact", "child0", "child1", "child2");
+    SpecialArtifact outputTreeArtifact = createTreeArtifact("outputTreeArtifact");
 
     OutputPathMapper mapper = new OutputPathMapper() {
       private int i = 0;
@@ -205,7 +204,7 @@
     return actionList.build();
   }
 
-  private Artifact createTreeArtifact(String path) {
+  private SpecialArtifact createTreeArtifact(String path) {
     PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = rootDirectory.getRelative(execPath);
     return new SpecialArtifact(
@@ -216,9 +215,9 @@
         SpecialArtifactType.TREE);
   }
 
-  private Artifact createAndPopulateTreeArtifact(String path, String... childRelativePaths)
+  private SpecialArtifact createAndPopulateTreeArtifact(String path, String... childRelativePaths)
       throws Exception {
-    Artifact treeArtifact = createTreeArtifact(path);
+    SpecialArtifact treeArtifact = createTreeArtifact(path);
     Map<TreeFileArtifact, FileArtifactValue> treeFileArtifactMap = new LinkedHashMap<>();
 
     for (String childRelativePath : childRelativePaths) {
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java
index bd8f78e..1699fc2 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ArtifactFunctionTest.java
@@ -178,7 +178,7 @@
 
   @Test
   public void testActionTreeArtifactOutput() throws Throwable {
-    Artifact artifact = createDerivedTreeArtifactWithAction("treeArtifact");
+    SpecialArtifact artifact = createDerivedTreeArtifactWithAction("treeArtifact");
     TreeFileArtifact treeFileArtifact1 = createFakeTreeFileArtifact(artifact, "child1", "hello1");
     TreeFileArtifact treeFileArtifact2 = createFakeTreeFileArtifact(artifact, "child2", "hello2");
 
@@ -192,13 +192,12 @@
   @Test
   public void testSpawnActionTemplate() throws Throwable {
     // artifact1 is a tree artifact generated by normal action.
-    Artifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1");
+    SpecialArtifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1");
     createFakeTreeFileArtifact(artifact1, "child1", "hello1");
     createFakeTreeFileArtifact(artifact1, "child2", "hello2");
 
-
     // artifact2 is a tree artifact generated by action template.
-    Artifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2");
+    SpecialArtifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2");
     TreeFileArtifact treeFileArtifact1 = createFakeTreeFileArtifact(artifact2, "child1", "hello1");
     TreeFileArtifact treeFileArtifact2 = createFakeTreeFileArtifact(artifact2, "child2", "hello2");
 
@@ -215,19 +214,19 @@
   @Test
   public void testConsecutiveSpawnActionTemplates() throws Throwable {
     // artifact1 is a tree artifact generated by normal action.
-    Artifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1");
+    SpecialArtifact artifact1 = createDerivedTreeArtifactWithAction("treeArtifact1");
     createFakeTreeFileArtifact(artifact1, "child1", "hello1");
     createFakeTreeFileArtifact(artifact1, "child2", "hello2");
 
     // artifact2 is a tree artifact generated by action template.
-    Artifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2");
+    SpecialArtifact artifact2 = createDerivedTreeArtifactOnly("treeArtifact2");
     createFakeTreeFileArtifact(artifact2, "child1", "hello1");
     createFakeTreeFileArtifact(artifact2, "child2", "hello2");
     actions.add(
         ActionsTestUtil.createDummySpawnActionTemplate(artifact1, artifact2));
 
     // artifact3 is a tree artifact generated by action template.
-    Artifact artifact3 = createDerivedTreeArtifactOnly("treeArtifact3");
+    SpecialArtifact artifact3 = createDerivedTreeArtifactOnly("treeArtifact3");
     TreeFileArtifact treeFileArtifact1 = createFakeTreeFileArtifact(artifact3, "child1", "hello1");
     TreeFileArtifact treeFileArtifact2 = createFakeTreeFileArtifact(artifact3, "child2", "hello2");
     actions.add(
@@ -270,13 +269,13 @@
         fullPath, middlemanRoot, middlemanRoot.getExecPath().getRelative(path), ALL_OWNER);
   }
 
-  private Artifact createDerivedTreeArtifactWithAction(String path) {
-    Artifact treeArtifact = createDerivedTreeArtifactOnly(path);
+  private SpecialArtifact createDerivedTreeArtifactWithAction(String path) {
+    SpecialArtifact treeArtifact = createDerivedTreeArtifactOnly(path);
     actions.add(new DummyAction(ImmutableList.<Artifact>of(), treeArtifact));
     return treeArtifact;
   }
 
-  private Artifact createDerivedTreeArtifactOnly(String path) {
+  private SpecialArtifact createDerivedTreeArtifactOnly(String path) {
     PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = root.getRelative(execPath);
     return new SpecialArtifact(
@@ -287,8 +286,8 @@
         SpecialArtifactType.TREE);
   }
 
-  private TreeFileArtifact createFakeTreeFileArtifact(Artifact treeArtifact,
-      String parentRelativePath, String content) throws Exception {
+  private TreeFileArtifact createFakeTreeFileArtifact(
+      SpecialArtifact treeArtifact, String parentRelativePath, String content) throws Exception {
     TreeFileArtifact treeFileArtifact = ActionInputHelper.treeFileArtifact(
         treeArtifact, PathFragment.create(parentRelativePath));
     Path path = treeFileArtifact.getPath();
@@ -361,9 +360,9 @@
       try {
         if (output.isTreeArtifact()) {
           TreeFileArtifact treeFileArtifact1 = ActionInputHelper.treeFileArtifact(
-              output, PathFragment.create("child1"));
+              (SpecialArtifact) output, PathFragment.create("child1"));
           TreeFileArtifact treeFileArtifact2 = ActionInputHelper.treeFileArtifact(
-              output, PathFragment.create("child2"));
+              (SpecialArtifact) output, PathFragment.create("child2"));
           TreeArtifactValue treeArtifactValue = TreeArtifactValue.create(ImmutableMap.of(
               treeFileArtifact1, FileArtifactValue.create(treeFileArtifact1),
               treeFileArtifact2, FileArtifactValue.create(treeFileArtifact2)));
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java
index d33c259..f7a989a 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/FilesystemValueCheckerTest.java
@@ -419,25 +419,25 @@
     // To decouple FileSystemValueTester checking from Action execution, we inject TreeArtifact
     // contents into ActionExecutionValues.
 
-    Artifact out1 = createTreeArtifact("one");
+    SpecialArtifact out1 = createTreeArtifact("one");
     TreeFileArtifact file11 = treeFileArtifact(out1, "fizz");
     FileSystemUtils.createDirectoryAndParents(out1.getPath());
     FileSystemUtils.writeContentAsLatin1(file11.getPath(), "buzz");
 
-    Artifact out2 = createTreeArtifact("two");
+    SpecialArtifact out2 = createTreeArtifact("two");
     FileSystemUtils.createDirectoryAndParents(out2.getPath().getChild("subdir"));
     TreeFileArtifact file21 = treeFileArtifact(out2, "moony");
     TreeFileArtifact file22 = treeFileArtifact(out2, "subdir/wormtail");
     FileSystemUtils.writeContentAsLatin1(file21.getPath(), "padfoot");
     FileSystemUtils.writeContentAsLatin1(file22.getPath(), "prongs");
 
-    Artifact outEmpty = createTreeArtifact("empty");
+    SpecialArtifact outEmpty = createTreeArtifact("empty");
     FileSystemUtils.createDirectoryAndParents(outEmpty.getPath());
 
-    Artifact outUnchanging = createTreeArtifact("untouched");
+    SpecialArtifact outUnchanging = createTreeArtifact("untouched");
     FileSystemUtils.createDirectoryAndParents(outUnchanging.getPath());
 
-    Artifact last = createTreeArtifact("zzzzzzzzzz");
+    SpecialArtifact last = createTreeArtifact("zzzzzzzzzz");
     FileSystemUtils.createDirectoryAndParents(last.getPath());
 
     SkyKey actionLookupKey =
@@ -614,7 +614,7 @@
         outputPath.getRelative(relPath), ArtifactRoot.asDerivedRoot(fs.getPath("/"), outputPath));
   }
 
-  private Artifact createTreeArtifact(String relPath) throws IOException {
+  private SpecialArtifact createTreeArtifact(String relPath) throws IOException {
     Path outputDir = fs.getPath("/bin");
     Path outputPath = outputDir.getRelative(relPath);
     outputDir.createDirectory();
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
index 675030c..30b6c4c 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactBuildTest.java
@@ -93,12 +93,12 @@
 
   Artifact in;
 
-  Artifact outOne;
+  SpecialArtifact outOne;
   TreeFileArtifact outOneFileOne;
   TreeFileArtifact outOneFileTwo;
   Button buttonOne = new Button();
 
-  Artifact outTwo;
+  SpecialArtifact outTwo;
   TreeFileArtifact outTwoFileOne;
   TreeFileArtifact outTwoFileTwo;
   Button buttonTwo = new Button();
@@ -187,10 +187,10 @@
   /** Unchanged TreeArtifact outputs should not cause reexecution. */
   @Test
   public void testCacheCheckingForTreeArtifactsDoesNotCauseReexecution() throws Exception {
-    Artifact outOne = createTreeArtifact("outputOne");
+    SpecialArtifact outOne = createTreeArtifact("outputOne");
     Button buttonOne = new Button();
 
-    Artifact outTwo = createTreeArtifact("outputTwo");
+    SpecialArtifact outTwo = createTreeArtifact("outputTwo");
     Button buttonTwo = new Button();
 
     TouchingTestAction actionOne = new TouchingTestAction(
@@ -482,7 +482,7 @@
 
   @Test
   public void testOutputsAreReadOnlyAndExecutable() throws Exception {
-    final Artifact out = createTreeArtifact("output");
+    final SpecialArtifact out = createTreeArtifact("output");
 
     TreeArtifactTestAction action =
         new TreeArtifactTestAction(out) {
@@ -515,7 +515,7 @@
 
   @Test
   public void testValidRelativeSymlinkAccepted() throws Exception {
-    final Artifact out = createTreeArtifact("output");
+    final SpecialArtifact out = createTreeArtifact("output");
 
     TreeArtifactTestAction action =
         new TreeArtifactTestAction(out) {
@@ -545,7 +545,7 @@
     reporter.removeHandler(failFastHandler);
     reporter.addHandler(storingEventHandler);
 
-    final Artifact out = createTreeArtifact("output");
+    final SpecialArtifact out = createTreeArtifact("output");
 
     TreeArtifactTestAction action =
         new TreeArtifactTestAction(out) {
@@ -585,7 +585,7 @@
     reporter.removeHandler(failFastHandler);
     reporter.addHandler(storingEventHandler);
 
-    final Artifact out = createTreeArtifact("output");
+    final SpecialArtifact out = createTreeArtifact("output");
 
     TreeArtifactTestAction action =
         new TreeArtifactTestAction(out) {
@@ -621,7 +621,7 @@
   public void testAbsoluteSymlinkAccepted() throws Exception {
     scratch.overwriteFile("/random/pointer");
 
-    final Artifact out = createTreeArtifact("output");
+    final SpecialArtifact out = createTreeArtifact("output");
 
     TreeArtifactTestAction action =
         new TreeArtifactTestAction(out) {
@@ -651,7 +651,7 @@
     reporter.removeHandler(failFastHandler);
     reporter.addHandler(storingEventHandler);
 
-    final Artifact out = createTreeArtifact("output");
+    final SpecialArtifact out = createTreeArtifact("output");
 
     TreeArtifactTestAction action =
         new TreeArtifactTestAction(out) {
@@ -729,7 +729,7 @@
   @Test
   public void testExpandedActionsBuildInActionTemplate() throws Throwable {
     // artifact1 is a tree artifact generated by a TouchingTestAction.
-    Artifact artifact1 = createTreeArtifact("treeArtifact1");
+    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
         artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
@@ -737,7 +737,7 @@
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
-    Artifact artifact2 = createTreeArtifact("treeArtifact2");
+    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
     SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         artifact1, artifact2);
     registerAction(actionTemplate);
@@ -769,7 +769,7 @@
     reporter.removeHandler(failFastHandler);
 
     // artifact1 is a tree artifact generated by a TouchingTestAction.
-    Artifact artifact1 = createTreeArtifact("treeArtifact1");
+    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
         artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
@@ -777,7 +777,7 @@
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
-    Artifact artifact2 = createTreeArtifact("treeArtifact2");
+    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
     SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         artifact1, artifact2);
     registerAction(actionTemplate);
@@ -816,7 +816,7 @@
     reporter.removeHandler(failFastHandler);
 
     // artifact1 is a tree artifact generated by a TouchingTestAction.
-    Artifact artifact1 = createTreeArtifact("treeArtifact1");
+    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
         artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
@@ -824,7 +824,7 @@
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
-    Artifact artifact2 = createTreeArtifact("treeArtifact2");
+    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
     SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         artifact1, artifact2);
     registerAction(actionTemplate);
@@ -863,7 +863,7 @@
     reporter.removeHandler(failFastHandler);
 
     // artifact1 is a tree artifact generated by a TouchingTestAction.
-    Artifact artifact1 = createTreeArtifact("treeArtifact1");
+    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     TreeFileArtifact treeFileArtifactA = ActionInputHelper.treeFileArtifact(
         artifact1, PathFragment.create("child1"));
     TreeFileArtifact treeFileArtifactB = ActionInputHelper.treeFileArtifact(
@@ -871,7 +871,7 @@
     registerAction(new TouchingTestAction(treeFileArtifactA, treeFileArtifactB));
 
     // artifact2 is a tree artifact generated by an action template.
-    Artifact artifact2 = createTreeArtifact("treeArtifact2");
+    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
     SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         artifact1, artifact2);
     registerAction(actionTemplate);
@@ -909,12 +909,12 @@
     reporter.removeHandler(failFastHandler);
 
     // artifact1 is created by a action that throws.
-    Artifact artifact1 = createTreeArtifact("treeArtifact1");
+    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     registerAction(
         new ThrowingDummyAction(ImmutableList.<Artifact>of(), ImmutableList.of(artifact1)));
 
     // artifact2 is a tree artifact generated by an action template.
-    Artifact artifact2 = createTreeArtifact("treeArtifact2");
+    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
     SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         artifact1, artifact2);
     registerAction(actionTemplate);
@@ -930,11 +930,11 @@
   @Test
   public void testEmptyInputAndOutputTreeArtifactInActionTemplate() throws Throwable {
     // artifact1 is an empty tree artifact which is generated by a single no-op dummy action.
-    Artifact artifact1 = createTreeArtifact("treeArtifact1");
+    SpecialArtifact artifact1 = createTreeArtifact("treeArtifact1");
     registerAction(new NoOpDummyAction(ImmutableList.<Artifact>of(), ImmutableList.of(artifact1)));
 
     // artifact2 is a tree artifact generated by an action template that takes artifact1 as input.
-    Artifact artifact2 = createTreeArtifact("treeArtifact2");
+    SpecialArtifact artifact2 = createTreeArtifact("treeArtifact2");
     SpawnActionTemplate actionTemplate = ActionsTestUtil.createDummySpawnActionTemplate(
         artifact1, artifact2);
     registerAction(actionTemplate);
@@ -955,7 +955,7 @@
     final Iterable<TreeFileArtifact> inputFiles;
     final Iterable<TreeFileArtifact> outputFiles;
 
-    TreeArtifactTestAction(final Artifact output, final String... subOutputs) {
+    TreeArtifactTestAction(final SpecialArtifact output, final String... subOutputs) {
       this(Runnables.doNothing(),
           null,
           ImmutableList.<TreeFileArtifact>of(),
@@ -1064,9 +1064,9 @@
     }
 
     /** Checks there's exactly one output, and returns it. */
-    Artifact getSoleOutput() {
+    SpecialArtifact getSoleOutput() {
       Iterator<Artifact> it = getOutputs().iterator();
-      Artifact r = it.next();
+      SpecialArtifact r = (SpecialArtifact) it.next();
       Preconditions.checkNotNull(r);
       Preconditions.checkState(!it.hasNext());
       Preconditions.checkState(r.equals(getPrimaryOutput()));
@@ -1078,7 +1078,8 @@
           treeFileArtifact(getSoleOutput(), PathFragment.create(outputName)));
     }
 
-    static List<TreeFileArtifact> asTreeFileArtifacts(final Artifact parent, String... files) {
+    static List<TreeFileArtifact> asTreeFileArtifacts(
+        final SpecialArtifact parent, String... files) {
       return Lists.transform(
           Arrays.asList(files),
           new Function<String, TreeFileArtifact>() {
@@ -1097,7 +1098,7 @@
       super(Runnables.doNothing(), outputPaths);
     }
 
-    TouchingTestAction(Runnable effect, Artifact output, String... outputPaths) {
+    TouchingTestAction(Runnable effect, SpecialArtifact output, String... outputPaths) {
       super(effect, asTreeFileArtifacts(output, outputPaths));
     }
 
@@ -1145,7 +1146,8 @@
   /** Copies the given TreeFileArtifact inputs to the given outputs, in respective order. */
   private static class CopyTreeAction extends TreeArtifactTestAction {
 
-    CopyTreeAction(Runnable effect, Artifact input, Artifact output, String... sourcesAndDests) {
+    CopyTreeAction(
+        Runnable effect, SpecialArtifact input, SpecialArtifact output, String... sourcesAndDests) {
       super(effect, input, asTreeFileArtifacts(input, sourcesAndDests), output,
           asTreeFileArtifacts(output, sourcesAndDests));
     }
@@ -1186,7 +1188,7 @@
     }
   }
 
-  private Artifact createTreeArtifact(String name) {
+  private SpecialArtifact createTreeArtifact(String name) {
     FileSystem fs = scratch.getFileSystem();
     Path execRoot = fs.getPath(TestUtils.tmpDir());
     PathFragment execPath = PathFragment.create("out").getRelative(name);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
index 4e3b242..96bc4be 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/TreeArtifactMetadataTest.java
@@ -85,13 +85,12 @@
   }
 
   private TreeArtifactValue doTestTreeArtifacts(Iterable<PathFragment> children) throws Exception {
-    Artifact output = createTreeArtifact("output");
+    SpecialArtifact output = createTreeArtifact("output");
     return doTestTreeArtifacts(output, children);
   }
 
-  private TreeArtifactValue doTestTreeArtifacts(Artifact tree,
-      Iterable<PathFragment> children)
-      throws Exception {
+  private TreeArtifactValue doTestTreeArtifacts(
+      SpecialArtifact tree, Iterable<PathFragment> children) throws Exception {
     TreeArtifactValue value = evaluateTreeArtifact(tree, children);
     assertThat(value.getChildPaths()).containsExactlyElementsIn(ImmutableSet.copyOf(children));
     assertThat(value.getChildren()).containsExactlyElementsIn(
@@ -200,10 +199,10 @@
     writeFile(path, contents);
   }
 
-  private Artifact createTreeArtifact(String path) throws IOException {
+  private SpecialArtifact createTreeArtifact(String path) throws IOException {
     PathFragment execPath = PathFragment.create("out").getRelative(path);
     Path fullPath = root.getRelative(execPath);
-    Artifact output =
+    SpecialArtifact output =
         new SpecialArtifact(
             fullPath,
             ArtifactRoot.asDerivedRoot(root, root.getRelative("out")),
@@ -254,7 +253,7 @@
       ActionLookupValue actionLookupValue =
           (ActionLookupValue) env.getValue(actionLookupData.getActionLookupNode());
       Action action = actionLookupValue.getAction(actionLookupData.getActionIndex());
-      Artifact output = Iterables.getOnlyElement(action.getOutputs());
+      SpecialArtifact output = (SpecialArtifact) Iterables.getOnlyElement(action.getOutputs());
       for (PathFragment subpath : testTreeArtifactContents) {
         try {
           TreeFileArtifact suboutput = ActionInputHelper.treeFileArtifact(output, subpath);