---
# System prepended metadata

title: ObligationCause performance

---

# ObligationCause performance

https://github.com/rust-lang/rust/pull/91030 has shown that even fairly small changes to the `ObligationCauseCode` can negatively impact performance. This doc summarizes a few of the causes and brainstorms solutions.

## What is ObligationCause?

When we register an obligation (like `T: Foo` in order to prove that `T` implements `Foo`) we also store a span pointing to the place that caused the obligation to be created. In case the obligation cannot be satisfied, we use this span to improve the diagnostic.

## So what's the problem?

A successful compilation has no need for obligation causes, as it never reported any errors. These causes are hashed and compared a few times, thus cause slowdowns just by the fact that they exist. Furthermore, making them more precise causes slowdowns by itself, because now two causes that were equal before now arent, preventing them from getting deduplicated.

## Solutions

### The sledgehammer

We could make the cause a generic parameter that. Then we can run typeck without any obligation causes. in case of errors, we report nothing, but instead rerun typeck with obligation causes. this makes sure we only have slowdowns if errors actually occur.

We can benchmark this by simply removing `ObligationCause` from the compiler. this will break many ui tests but will produce a working compiler that we can run benchmarks on.

## More aggressive deduplication

During obligation deduplication, we could merge or just drop causes if the obligation is otherwise equal.