Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1 million item array spends inordinate time on error path of typechecking #137678

Open
nabijaczleweli opened this issue Feb 26, 2025 · 6 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.

Comments

@nabijaczleweli
Copy link
Contributor

nabijaczleweli commented Feb 26, 2025

Code

(The actual data is for indices in a 100³ gilbert curve but isn't relevant here.)

$ { echo '['; seq $(( 100 * 100 * 100 )) | sed 's/.*/(0,0,0),/'; echo ']'; } > 100.rs
const GRID_SIZE: usize = 100;
static GRID_GILBERT: [(u8,u8,u8); GRID_SIZE*GRID_SIZE*GRID_SIZE] = include!("100.rs");
fn main() {}

this is the good state

$ time rustc bugowcy.rs
warning: constant `GRID_SIZE` is never used
 --> bugowcy.rs:1:7
  |
1 | const GRID_SIZE: usize = 100;
  |       ^^^^^^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: static `GRID_GILBERT` is never used
 --> bugowcy.rs:2:8
  |
2 | static GRID_GILBERT: [(u8,u8,u8); GRID_SIZE*GRID_SIZE*GRID_SIZE] = include!("100.rs");
  |        ^^^^^^^^^^^^

warning: 2 warnings emitted


real    0m32.666s
user    0m0.031s
sys     0m0.015s

Change line 2 to

static GRID_GILBERT: &[(u8,u8,u8)] = include!("100.rs");

to trigger

$ time rustc bugowcy.rs
error[E0308]: mismatched types
       --> 100.rs:1:1
        |
1       | / [
2       | | (0,0,0),
3       | | (0,0,0),
4       | | (0,0,0),
...       |
1000001 | | (0,0,0),
1000002 | | ]
        | |_^ expected `&[(u8, u8, u8)]`, found `[({integer}, {integer}, {integer}); 1000000]`
        |
        = note: expected reference `&'static [(u8, u8, u8)]`
                       found array `[({integer}, {integer}, {integer}); 1000000]`
help: consider borrowing here
        |
1       | &[
        | +

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0308`.

real    2m12.583s
user    0m0.000s
sys     0m0.000s

Current output

$ time cargo build -r
warning: `D:\Users\nabijaczleweli\.cargo\config` is deprecated in favor of `config.toml`
note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml`
warning: no edition set: defaulting to the 2015 edition while the latest is 2021
   Compiling posteriser v0.0.0 (P:\Rust\posteriser)
error[E0308]: mismatched types
       --> src\../gilbert/100.rs:1:1
        |
1       | / [
2       | | (0,0,0),
3       | | (0,1,0),
4       | | (0,1,1),
...       |
1000001 | | (99,0,0),
1000002 | | ]
        | |_^ expected `&[(u8, u8, u8)]`, found `[(..., ..., ...); 1000000]`
        |
        = note: expected reference `&'static [(u8, u8, u8)]`
                       found array `[({integer}, {integer}, {integer}); 1000000]`
help: consider borrowing here
        |
1       | &[
        | +

error[E0277]: `&&[(u8, u8, u8)]` is not an iterator
   --> src\posterise_gpu.rs:825:30
    |
825 |             for (x, y, z) in &GRID_GILBERT {
    |                              ^^^^^^^^^^^^^ `&&[(u8, u8, u8)]` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `&&[(u8, u8, u8)]`
    = note: required for `&&[(u8, u8, u8)]` to implement `IntoIterator`
help: consider removing the leading `&`-reference
    |
825 -             for (x, y, z) in &GRID_GILBERT {
825 +             for (x, y, z) in GRID_GILBERT {
    |

real 2m14s


The base speed of a full build is 42s.

Desired output

$ time cargo build -r
warning: `D:\Users\nabijaczleweli\.cargo\config` is deprecated in favor of `config.toml`
note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml`
warning: no edition set: defaulting to the 2015 edition while the latest is 2021
   Compiling posteriser v0.0.0 (P:\Rust\posteriser)
error[E0308]: mismatched types
       --> src\../gilbert/100.rs:1:1
        | expected `&[(u8, u8, u8)]`, found `[(..., ..., ...); 1000000]`
        |
        = note: expected reference `&'static [(u8, u8, u8)]`
                       found array `[({integer}, {integer}, {integer}); 1000000]`

error[E0277]: `&&[(u8, u8, u8)]` is not an iterator
   --> src\posterise_gpu.rs:825:30
    |
825 |             for (x, y, z) in &GRID_GILBERT {
    |                              ^^^^^^^^^^^^^ `&&[(u8, u8, u8)]` is not an iterator
    |
    = help: the trait `Iterator` is not implemented for `&&[(u8, u8, u8)]`
    = note: required for `&&[(u8, u8, u8)]` to implement `IntoIterator`
help: consider removing the leading `&`-reference
    |
825 -             for (x, y, z) in &GRID_GILBERT {
825 +             for (x, y, z) in GRID_GILBERT {
    |

real <40s

Rationale and extra context

I think in this case (and in general) having rustc churn for two full minutes is. Not good. And value to the user is bigger when you get the error without source-level diagnostics.

Rust Version

$ rustc --version --verbose
rustc 1.84.1 (e71f9a9a9 2025-01-27)
binary: rustc
commit-hash: e71f9a9a98b0faf423844bf0ba7438f29dc27d58
commit-date: 2025-01-27
host: x86_64-pc-windows-gnu
release: 1.84.1
LLVM version: 19.1.5
@nabijaczleweli nabijaczleweli added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Feb 26, 2025
@fmease fmease added the I-compiletime Issue: Problems and improvements with respect to compile times. label Feb 26, 2025
@saethlin
Copy link
Member

Spends minutes (real) trying to format a diagnostic.

How did you deduce that the time is spent in formatting?

@nabijaczleweli
Copy link
Contributor Author

nabijaczleweli commented Feb 26, 2025

If I make it not produce a diagnostic then it doesn't take minutes. I may be using a "format" more generically than you would, but outputting the diagnostic is as good as instant, so formatting -- preparing data to output -- must be the only other step. You probably have established nomenclature for this.

@workingjubilee
Copy link
Member

"make it not produce a diagnostic"?

what do you mean?

@nabijaczleweli
Copy link
Contributor Author

If I fix the error it doesn't produce the diagnostic and takes 32s. Writing the diagnostic takes approximately 0 time, therefore formatting the diagnostic takes at least 2:12-0:32=1:40. I believe it probably shouldn't take this long, and it would've been better for it to have taken 32s and produce just a type-level diagnostic.

@workingjubilee
Copy link
Member

workingjubilee commented Feb 27, 2025

Hm.

Are you sure this "formatting" of the diagnostic is not something like, for instance, the typechecker not being able to quickly solve the problem "what is the type of this?" and then examining the entire array to determine if there is a type it can coerce the entire array to and then attempting to apply a coercion to the entire array to interpret the type as something else and seeing if then it would resolve to something with the correct type?

@workingjubilee workingjubilee changed the title Spends minutes (real) trying to format a diagnostic. It succeeds! But somehow I don't feel this should take additional minutes? I'd much rather it bail and produce no source-level diagnostic, only the types. Or something. 1 million item array spends inordinate time on error path of typechecking Feb 27, 2025
@nabijaczleweli
Copy link
Contributor Author

nabijaczleweli commented Feb 27, 2025 via email

@saethlin saethlin added the T-types Relevant to the types team, which will review and decide on the PR/issue. label Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints I-compiletime Issue: Problems and improvements with respect to compile times. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-types Relevant to the types team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants