A project takes more than 1 minute to do a simple cargo check

Hey, folks! Newbie here. I have a project that takes a lot of time to do a simple cargo check. I believe that all libs already compiled, this test was made after a cargo build. I just add a blank line in main.rs then execute cargo check. This process takes more than a minute. I tested in a desktop i7 4790 Windows 10 (AV disabled) and a Lenovo L340L i7 9750h with Linux Fedora 31, both with SSD.

+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| Item                                             | Self time | % of total time | Time     | Item count | Incremental load time | Incremental result hashing time |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| typeck                                           | 58.04s    | 72.137          | 60.88s   | 82         | 12.31ms               | 3.91ms                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| LLVM_module_codegen_emit_obj                     | 4.64s     | 5.772           | 4.64s    | 23         | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| run_linker                                       | 4.23s     | 5.260           | 4.23s    | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| evaluate_obligation                              | 2.58s     | 3.203           | 2.76s    | 9256       | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| LLVM_passes                                      | 1.65s     | 2.049           | 1.65s    | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| codegen_module                                   | 1.48s     | 1.845           | 1.98s    | 22         | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| metadata_decode_entry_exported_symbols           | 1.07s     | 1.333           | 1.09s    | 291        | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| expand_crate                                     | 1.03s     | 1.277           | 1.17s    | 1          | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
| incr_comp_encode_dep_graph                       | 650.33ms  | 0.808           | 650.33ms | 540550     | 0.00ns                | 0.00ns                          |
+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+

...

+--------------------------------------------------+-----------+-----------------+----------+------------+-----------------------+---------------------------------+
Total cpu time: 80.4545914s

My first suspicion was the sqlx library that your macro connects to the database. But I enabled offline mode and the time hasn't changed. I enabled the use of sccache on Linux but it also improved nothing.

It seems that time stays in this step called "typeck". Does anyone have any suggestions on how I can improve this time?

--EDIT
Tested with
rustc 1.53
rustc 1.54
rustc 1.56.0-nightly

Thanks in advance!

Type-checking that takes a whole minute is abnormal. Your code may be running into a bug in the compiler (e.g. something is accidentally quadratic).

It would be helpful if you could create a minimal case that reproduces the slowdown and report it as a rustc bug.

Alternatively, profile rustc itself to see where it spends time exactly. It may give a hint about which type is causing slowdown. Such drastic slowdowns have happened before with deeply nested async functions and closures.

6 Likes

You might be able to see which crate is making typeck take forever by looking at the graph generated by cargo +nightly build -Z timings. That should give you a point to start from.

2 Likes

Given the limited info, I have no idea what is going no. The rest of this is hypothesis since you mentioned 'sqlx'

If there is anything similar to row-types being implemented in sqlx, it might be based on 'heterogeneous list' technique -- and that often ends up being macros that expands to complicated traits / structs that take very very very long time to type check.

Sqlx without offline can take a while are you sure you got offline setup correctly?

You have a sqlx-data.json file from sqlx prepare? It shouldn't cargo check if you rename that file.

If that does check without that file then you're missing the environment variable (could be set in a .env at the root of the workspace/crate along with DATABASE_URL)
SQLX_OFFLINE=true

Hey, folks! I follow the suggestion of @kornel to create a minimal case. After doing that, I finally found out that the cause: there is an issue with Axum crate that results in this long time in rustc.
https://github.com/rust-lang/rust/issues/87924

Hope this is fixed soon.

Many thanks to everyone who brought suggestions for me. You are the best.

1 Like

This issue has been fixed in axum. See https://github.com/tokio-rs/axum/issues/145

3 Likes

Is there an ELI5 for the root cause? I see that it has been fixed, but can't find what caused the original slowdown.

The PRs that improved things were

  • #198 - Which removed some trait bounds from the handle_error method. For some reason Rust was slow at checking the bounds at that time. The bounds are now only checked on impl Service for HandleError.
  • #184 - Which made some very common types smaller. Basically instead of three nested types, it was flattened to only two nested types.
3 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.