Apart from the general [keep rules](https://developer.android.com/topic/performance/app-optimization/add-keep-rules), [additional keep rule types](https://developer.android.com/topic/performance/app-optimization/additional-rule-types), and
[global options](https://developer.android.com/topic/performance/app-optimization/global-options), you can use certain rules to troubleshoot your
optimization.

## `-checkdiscard`

The `-checkdiscard` rule lets you check whether R8 has successfully
discarded a class or its member that you expected to be removed. If the
specified class or member isn't discarded, the build fails.

The syntax for `-checkdiscard` is as follows:


    -checkdiscard https://developer.android.com/topic/performance/app-optimization/add-keep-rules#class-spec

In the following example, the build fails if either the `userId` field or the `setLabel()` method
from the `com.example.models.User` class is retained:

    -checkdiscard class com.example.models.User{
      private java.lang.String userId;
      public void setLabel(java.lang.String);
    }

The class's code might still be present in the app if its methods were inlined
into other classes. To make sure that the code has been completely removed and
not just inlined, add a corresponding rule that prevents R8 from performing
optimizations on the target class, by combining `-checkdiscard` with a
[`-keep,allowshrinking`](https://developer.android.com/topic/performance/app-optimization/add-keep-rules#keep-option-modifier) rule. This prohibits optimizations such as class
merging and inlining. If the `-checkdiscard` rule passes, then none of the
contents from the matched classes are in the optimized app.

The following example demonstrates this usage:

    # Either keep or remove the class, don't rename or otherwise optimize it
    -keep,allowshrinking class com.example.foo { *; }

    # Verify that the class and all of its fields and methods are removed.
    -checkdiscard class com.example.foo

## `-whyareyoukeeping`

Use the `-whyareyoukeeping` rule to determine why R8 kept a specific class,
field, or method in your app's build. An item can be kept for multiple reasons;
however, this rule only provides the one that explains the shortest path to the
item from a kept item. If you remove this path from your code, you might still
see the item retained but for a different reason.

The possible reasons are:

- **A keep rule**: The keep rule can be from the app, a consumed library, or
  rules generated by AAPT (Android Asset Packaging Tool).

  > [!NOTE]
  > **Note:** The keep rules generated by AAPT are not present when [optimized
  > resource shrinking](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization#optimize-resource-shrinking) is enabled.

- **Transitive references from kept code or resources**: If code or XML (such as
  layouts) is retained by R8, anything it statically references is kept.

The syntax is:


    -whyareyoukeeping https://developer.android.com/topic/performance/app-optimization/add-keep-rules#class-spec

For example:

    -whyareyoukeeping class com.example.foo.MainActivity {
      private void setLabel(...);
    }

The output is printed to the console.

If you don't have any rule keeping `setLabel()`, the output is:

    com.example.foo.MainActivity
    |- is referenced in keep rule:
    |  /app/build/intermediates/aapt_proguard_file/release/processReleaseResources/aapt_rules.txt:4:1
    Nothing is keeping void com.example.foo.MainActivity.setLabel()

If you have a keep rule targeting `setLabel()`, the output is similar to the
following:

    com.example.foo.MainActivity
    |- is referenced in keep rule:
    | /app/proguard-rules.pro:23:1
    void com.example.foo.MainActivity.setLabel()
    |- is referenced in keep rule:
    |  /app/proguard-rules.pro:23:1

> [!CAUTION]
> **Caution:** The `-whyareyoukeeping` rule is only meant for debugging locally. Don't check it into your codebase. Including this rule can slow down your build.