Handle InterruptedException thrown from @SkylarkCallable methods appropriately.

RELNOTES: None.
PiperOrigin-RevId: 193370435
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java b/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
index 16d0c64..c2cb348 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NativeInfo.java
@@ -36,7 +36,16 @@
       return values.get(name);
     } else if (hasField(name)) {
       MethodDescriptor methodDescriptor = FuncallExpression.getStructField(this.getClass(), name);
-      return FuncallExpression.invokeStructField(methodDescriptor, name, this);
+      try {
+        return FuncallExpression.invokeStructField(methodDescriptor, name, this);
+      } catch (InterruptedException exception) {
+        // Struct fields on NativeInfo objects are supposed to behave well and not throw
+        // exceptions, as they should be logicless field accessors. If this occurs, it's
+        // indicative of a bad NativeInfo implementation.
+        throw new IllegalStateException(
+            String.format("Access of field %s was unexpectedly interrupted, but should be "
+                + "uninterruptible. This is indicative of a bad provider implementation.", name));
+      }
     } else {
       return null;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
index 86313c1..4a1507b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java
@@ -82,7 +82,7 @@
    * Returns the field of the given name of the struct objValue, or null if no such field exists.
    */
   public static Object eval(Object objValue, String name,
-      Location loc, Environment env) throws EvalException {
+      Location loc, Environment env) throws EvalException, InterruptedException {
     if (objValue instanceof SkylarkClassObject) {
       try {
         return ((SkylarkClassObject) objValue).getValue(name);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index 1928fce..dba8ffc 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -17,6 +17,7 @@
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Throwables;
 import com.google.common.cache.CacheBuilder;
 import com.google.common.cache.CacheLoader;
 import com.google.common.cache.LoadingCache;
@@ -353,13 +354,14 @@
    * @throws EvalException if there was an issue evaluating the method
    */
   public static Object invokeStructField(
-      MethodDescriptor methodDescriptor, String fieldName, Object obj) throws EvalException {
+      MethodDescriptor methodDescriptor, String fieldName, Object obj)
+      throws EvalException, InterruptedException {
     Preconditions.checkArgument(methodDescriptor.getAnnotation().structField());
     return callMethod(methodDescriptor, fieldName, obj, new Object[0], Location.BUILTIN, null);
   }
 
   static Object callMethod(MethodDescriptor methodDescriptor, String methodName, Object obj,
-      Object[] args, Location loc, Environment env) throws EvalException {
+      Object[] args, Location loc, Environment env) throws EvalException, InterruptedException {
     try {
       Method method = methodDescriptor.getMethod();
       if (obj == null && !Modifier.isStatic(method.getModifiers())) {
@@ -401,6 +403,8 @@
       if (e.getCause() instanceof FuncallException) {
         throw new EvalException(loc, e.getCause().getMessage());
       } else if (e.getCause() != null) {
+        Throwables.throwIfInstanceOf(e.getCause(), InterruptedException.class);
+
         throw new EvalExceptionWithJavaCause(loc, e.getCause());
       } else {
         // This is unlikely to happen
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index a6b865e..fe519b0 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -745,7 +745,7 @@
         @SuppressWarnings("unused")
         public Object invoke(
             Object obj, String name, Object defaultValue, Location loc, Environment env)
-            throws EvalException {
+            throws EvalException, InterruptedException {
           Object result = DotExpression.eval(obj, name, loc, env);
           if (result == null) {
             // 'Real' describes methods with structField() == false. Because DotExpression.eval