/**
  * Determine whether the given field's type is changed when type parameters from the defining
  * type's declaration are replaced with the actual type arguments from the defining type.
  *
  * @param baseField the base field
  * @param definingType the type defining the parameters and arguments to be used in the
  *     substitution
  * @return true if the type is changed by type substitution.
  */
 private static boolean isChangedByTypeSubstitution(
     FieldElement baseField, InterfaceType definingType) {
   Type[] argumentTypes = definingType.getTypeArguments();
   if (baseField != null && argumentTypes.length != 0) {
     Type baseType = baseField.getType();
     Type[] parameterTypes = definingType.getElement().getType().getTypeArguments();
     if (baseType != null) {
       Type substitutedType = baseType.substitute(argumentTypes, parameterTypes);
       if (!baseType.equals(substitutedType)) {
         return true;
       }
     }
     // If the field has a propagated type, then we need to check whether the propagated type
     // needs substitution.
     Type basePropagatedType = baseField.getPropagatedType();
     if (basePropagatedType != null) {
       Type substitutedPropagatedType =
           basePropagatedType.substitute(argumentTypes, parameterTypes);
       if (!basePropagatedType.equals(substitutedPropagatedType)) {
         return true;
       }
     }
   }
   return false;
 }