Skip to content

Slow coherence checking and type checking. #138828

Open

Description

@coolcatcoder

I was working on creating a crate and encountered some unexpectedly long compile times.
I don't have a minimal reproduction, but I have expanded my macros, and copied the code into a playground.

It occurs on all channels. It is still pretty bad even with the parallel front-end enabled. According to time-passes, the biggest culprits were coherence checking and type checking.

time:   6.038; rss:   80MB ->  272MB ( +192MB)  coherence_checking
time:   6.084; rss:   80MB ->  274MB ( +195MB)  type_check_crate

My use case is clearly atypical, so I will understand if you consider this frivolous and close it. (Although, when I searched to see if my issue had already been reported, I did notice submitted situations that were arguably even less likely to be encountered by anyone.)

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Mar 22, 2025
  2. moxian commented on Mar 22, 2025

    @moxian
    Contributor

    Bisection: While this code has always been slow, it took an extra ~30% comptime hit in nightly-2024-02-15.

    //  nightly-2024-02-15
    time:   0.006; rss:   34MB ->   38MB (   +4MB)  coherence_checking
    time:  12.322; rss:   38MB ->  236MB ( +198MB)  wf_checking
    time:  12.400; rss:   31MB ->  240MB ( +208MB)  type_check_crate
    
    // nightly-2024-02-14
    time:   0.006; rss:   34MB ->   38MB (   +4MB)  coherence_checking
    time:   9.725; rss:   38MB ->  220MB ( +182MB)  wf_checking
    time:   9.802; rss:   31MB ->  224MB ( +192MB)  type_check_crate
    

    Unfortunately that nightly has several type-level PRs landing, making it hard to pinpoint regression precisely, but #118882 sounds most likely

    cargo-bisect-rustc output

    Regression in nightly-2024-02-15


    converted 2024-02-14 to a84bb95
    converted 2024-02-15 to ee9c7c9
    get_commits_between returning commits, len: 9

    Edit: and also another ~20% hit several weeks prior in nightly-2024-01-18. Likely #120019

    // nightly-2024-01-17
    time:   0.007; rss:   34MB ->   38MB (   +4MB)  coherence_checking
    time:   8.118; rss:   38MB ->  206MB ( +168MB)  wf_checking
    time:   8.207; rss:   32MB ->  210MB ( +178MB)  type_check_crate
    
    cargo-bisect-rustc out
    ********************************************************************************
    Regression in nightly-2024-01-18
    ********************************************************************************
    converted 2024-01-17 to 098d4fd74c078b12bfc2e9438a2a04bc18b393bc
    converted 2024-01-18 to 6ae4cfbbb080cafea7f6be48ce47678ee057352c
    get_commits_between returning commits, len: 9
      commit[0] 2024-01-16: Auto merge of #119977 - Mark-Simulacrum:defid-cache, r=cjgillot
      commit[1] 2024-01-17: Auto merge of #120036 - weihanglo:update-cargo, r=weihanglo
      commit[2] 2024-01-17: Auto merge of #120019 - lcnr:fn-wf, r=BoxyUwU
      commit[3] 2024-01-17: Auto merge of #119651 - novafacing:proc_macro_c_str_literals, r=Amanieu
      commit[4] 2024-01-17: Auto merge of #119922 - nnethercote:fix-Diag-code-is_lint, r=oli-obk
      commit[5] 2024-01-17: Auto merge of #119111 - michaelwoerister:measureme-11, r=Mark-Simulacrum
      commit[6] 2024-01-17: Auto merge of #119670 - cjgillot:gvn-arithmetic, r=oli-obk
      commit[7] 2024-01-17: Auto merge of #119930 - Urgau:check-cfg-empty-values-means-empty, r=petrochenkov
      commit[8] 2024-01-17: Auto merge of #118708 - davidtwco:target-tier-assembly-test, r=Mark-Simulacrum
    

    @rustbot label: +T-compiler +T-types +A-coherence +I-compiletime -needs-triage +A-trait-system

  3. added
    I-compiletimeIssue: Problems and improvements with respect to compile times.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    T-typesRelevant to the types team, which will review and decide on the PR/issue.
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Mar 22, 2025
  4. moxian commented on Mar 23, 2025

    @moxian
    Contributor

    Smaller:

    use core::{marker::PhantomData, ops::Deref};
    
    struct DerefOnly<T: ?Sized>(PhantomData<T>);
    
    impl<T: Deref> Deref for DerefOnly<T> {
        type Target = DerefOnly<T::Target>;
    
        fn deref(&self) -> &Self::Target {
            &DerefOnly(PhantomData)
        }
    }
    
    struct Empty;
    
    impl DerefOnly<Empty> {
        fn whatever(&self) {}
    }
    
    // copy-paste the function a couple of times if your pc is too fast to notice
    fn foo_1() {
        DerefOnly(PhantomData::<
      &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Empty,
            >).whatever();
    }
    fn foo_2() {
        DerefOnly(PhantomData::<
      &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Empty,
            >).whatever();
    }
    
    fn main() {}

    What's happening is we create a let x = DerefOnly{0: PhantomData<&&..&&Empty>}, and try to call a method .whatever() on it. The type we have at hand doesn't have said method but the type x.deref().deref()......deref() does. And it's this deref chain that's taking us some time to traverse. I think... I'm by no means an expert.

  5. diondokter commented on Jul 29, 2025

    @diondokter
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-coherenceArea: CoherenceA-trait-systemArea: Trait systemC-bugCategory: This is a bug.I-compiletimeIssue: Problems and improvements with respect to compile times.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions