Some constraint enforcement tweaks:

1) Exclude host dependencies from constraint checking.
2) Check output files with the environment specs of their generating rules.
3) Provide a more generalized way to opt certain rule classes out of
   constraint checking (this fixes accidental checking on config_setting
   rules, which didn't really make sense).

--
MOS_MIGRATED_REVID=87963638
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 23f1c97..17866c5 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -432,6 +432,7 @@
     private SkylarkEnvironment ruleDefinitionEnvironment = null;
     private Set<Class<?>> configurationFragments = new LinkedHashSet<>();
     private boolean failIfMissingConfigurationFragment;
+    private boolean supportsConstraintChecking = true;
 
     private final Map<String, Attribute> attributes = new LinkedHashMap<>();
 
@@ -459,6 +460,7 @@
         }
         configurationFragments.addAll(parent.requiredConfigurationFragments);
         failIfMissingConfigurationFragment |= parent.failIfMissingConfigurationFragment;
+        supportsConstraintChecking = parent.supportsConstraintChecking;
 
         for (Attribute attribute : parent.getAttributes()) {
           String attrName = attribute.getName();
@@ -511,7 +513,7 @@
           configuredTargetFactory, validityPredicate, preferredDependencyPredicate,
           ImmutableSet.copyOf(advertisedProviders), configuredTargetFunction,
           ruleDefinitionEnvironment, configurationFragments, failIfMissingConfigurationFragment,
-          attributes.values().toArray(new Attribute[0]));
+          supportsConstraintChecking, attributes.values().toArray(new Attribute[0]));
     }
 
     /**
@@ -743,6 +745,19 @@
     }
 
     /**
+     * Exempts rules of this type from the constraint enforcement system. This should only be
+     * applied to rules that are intrinsically incompatible with constraint checking (any
+     * application of this method weakens the reach and strength of the system).
+     *
+     * @param reason user-informative message explaining the reason for exemption (not used)
+     */
+    public <TYPE> Builder exemptFromConstraintChecking(String reason) {
+      Preconditions.checkState(this.supportsConstraintChecking);
+      this.supportsConstraintChecking = false;
+      return this;
+    }
+
+    /**
      * Returns an Attribute.Builder object which contains a replica of the
      * same attribute in the parent rule if exists.
      *
@@ -841,6 +856,14 @@
    */
   private final boolean failIfMissingConfigurationFragment;
 
+
+  /**
+   * Determines whether instances of this rule should be checked for constraint compatibility
+   * with their dependencies and the rules that depend on them. This should be true for
+   * everything except for rules that are intrinsically incompatible with the constraint system.
+   */
+  private final boolean supportsConstraintChecking;
+
   /**
    * Constructs an instance of RuleClass whose name is 'name', attributes
    * are 'attributes'. The {@code srcsAllowedFiles} determines which types of
@@ -875,6 +898,7 @@
       @Nullable UserDefinedFunction configuredTargetFunction,
       @Nullable SkylarkEnvironment ruleDefinitionEnvironment,
       Set<Class<?>> allowedConfigurationFragments, boolean failIfMissingConfigurationFragment,
+      boolean supportsConstraintChecking,
       Attribute... attributes) {
     this.name = name;
     this.targetKind = name + " rule";
@@ -896,6 +920,7 @@
     this.outputsDefaultExecutable = outputsDefaultExecutable;
     this.requiredConfigurationFragments = ImmutableSet.copyOf(allowedConfigurationFragments);
     this.failIfMissingConfigurationFragment = failIfMissingConfigurationFragment;
+    this.supportsConstraintChecking = supportsConstraintChecking;
 
     // create the index:
     int index = 0;
@@ -1069,6 +1094,13 @@
   }
 
   /**
+   * Returns true if rules of this type can be used with the constraint enforcement system.
+   */
+  public boolean supportsConstraintChecking() {
+    return supportsConstraintChecking;
+  }
+
+  /**
    * Helper function for {@link RuleFactory#createAndAddRule}.
    */
   Rule createRuleWithLabel(Package.AbstractBuilder<?, ?> pkgBuilder, Label ruleLabel,