Skip to content

Exponential compile time with broken huge nested enum #104162

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

Open
jruderman opened this issue Nov 8, 2022 · 1 comment
Open

Exponential compile time with broken huge nested enum #104162

jruderman opened this issue Nov 8, 2022 · 1 comment
Labels
C-bug Category: This is a bug. I-compiletime Issue: Problems and improvements with respect to compile times.

Comments

@jruderman
Copy link
Contributor

Long ago, in #42747, an exponential compile time issue was fixed for huge nested enums.

Fuzzing discovered that deleting lines from src/test/ui/enum/issue-42747.rs, and thus introducing a resolve error, brings back exponential compile time.

Code

macro_rules! fooN {
    ($cur:ident $prev:ty) => {
        #[allow(dead_code)]
        enum $cur {
            Empty,
            First($prev),
            Second($prev),
            Third($prev),
            Fourth($prev),
        }
    }
}

fooN!(Foo16 Foo15);  //~ ERROR cannot find type `Foo15` in this scope
fooN!(Foo17 Foo16);
fooN!(Foo18 Foo17);
fooN!(Foo19 Foo18);
fooN!(Foo20 Foo19);
fooN!(Foo21 Foo20);
fooN!(Foo22 Foo21);
fooN!(Foo23 Foo22);
fooN!(Foo24 Foo23);
fooN!(Foo25 Foo24);
fooN!(Foo26 Foo25);
fooN!(Foo27 Foo26);

fn main() {
    let _foo = Foo27::Empty;
}

Where it's slow

The slow passes are wf_checking, item_bodies_checking, and type_check_crate. Memory usage is also much higher than with the non-erroneous, original test.

Note that the error is emitted much earlier, in resolve_report_errors.

Output with -Z time-passes

time:   0.010; rss:   21MB ->   22MB (   +1MB)	parse_crate
time:   0.000; rss:   22MB ->   22MB (   +0MB)	attributes_injection
time:   0.000; rss:   22MB ->   22MB (   +0MB)	plugin_loading
time:   0.002; rss:   22MB ->   22MB (   +0MB)	crate_injection
time:   0.035; rss:   22MB ->   26MB (   +3MB)	expand_crate
time:   0.036; rss:   22MB ->   26MB (   +4MB)	macro_expand_crate
time:   0.000; rss:   26MB ->   26MB (   +0MB)	maybe_building_test_harness
time:   0.004; rss:   26MB ->   26MB (   +0MB)	AST_validation
time:   0.000; rss:   26MB ->   26MB (   +0MB)	maybe_create_a_macro_crate
time:   0.000; rss:   26MB ->   26MB (   +0MB)	finalize_imports
time:   0.001; rss:   26MB ->   26MB (   +0MB)	compute_effective_visibilities
time:   0.000; rss:   26MB ->   27MB (   +0MB)	finalize_macro_resolutions
time:   0.029; rss:   27MB ->   38MB (  +11MB)	late_resolve_crate
time:   0.000; rss:   38MB ->   38MB (   +0MB)	resolve_check_unused
error[E0412]: cannot find type `Foo15` in this scope
  --> *.rs:14:13
   |
4  |         enum $cur {
   |         --------- similarly named enum `Foo16` defined here
...
14 | fooN!(Foo16 Foo15);  //~ ERROR cannot find type `Foo15` in this scope
   |             ^^^^^ help: an enum with a similar name exists: `Foo16`

time:   0.003; rss:   38MB ->   38MB (   +0MB)	resolve_report_errors
time:   0.001; rss:   38MB ->   38MB (   +0MB)	resolve_postprocess
time:   0.034; rss:   26MB ->   38MB (  +12MB)	resolve_crate
time:   0.000; rss:   38MB ->   38MB (   +0MB)	complete_gated_feature_checking
time:   0.003; rss:   38MB ->   39MB (   +0MB)	early_lint_checks
time:   0.089; rss:   22MB ->   39MB (  +17MB)	configure_and_expand
time:   0.001; rss:   39MB ->   39MB (   +0MB)	prepare_outputs
time:   0.003; rss:   39MB ->   39MB (   +0MB)	setup_global_ctxt
time:   0.001; rss:   40MB ->   40MB (   +0MB)	drop_ast
time:   0.051; rss:   39MB ->   40MB (   +1MB)	looking_for_entry_point
time:   0.001; rss:   40MB ->   40MB (   +0MB)	looking_for_derive_registrar
time:   0.000; rss:   41MB ->   41MB (   +0MB)	unused_lib_feature_checking
time:   0.068; rss:   39MB ->   41MB (   +2MB)	misc_checking_1
time:   0.016; rss:   41MB ->   42MB (   +1MB)	type_collecting
time:   0.000; rss:   42MB ->   42MB (   +0MB)	impl_wf_inference
time:   0.004; rss:   42MB ->   42MB (   +0MB)	coherence_checking
time:  11.404; rss:   42MB ->   93MB (  +51MB)	wf_checking
time:   0.115; rss:   93MB ->   94MB (   +1MB)	item_types_checking
time:  32.556; rss:   94MB ->  166MB (  +72MB)	item_bodies_checking
time:  44.123; rss:   41MB ->  167MB ( +126MB)	type_check_crate
time:   0.001; rss:  167MB ->  167MB (   +0MB)	serialize_dep_graph
time:   0.045; rss:  167MB ->   24MB ( -143MB)	free_global_ctxt
error: aborting due to previous error

For more information about this error, try `rustc --explain E0412`.
time:  44.474; rss:   13MB ->   23MB (  +10MB)	total

Version

rustc 1.67.0-nightly (7eef946fc 2022-11-06)
binary: rustc
commit-hash: 7eef946fc0e0eff40e588eab77b09b287accbec3
commit-date: 2022-11-06
host: x86_64-apple-darwin
release: 1.67.0-nightly
LLVM version: 15.0.4

@rustbot label +I-compiletime

@jruderman jruderman added the C-bug Category: This is a bug. label Nov 8, 2022
@rustbot rustbot added the I-compiletime Issue: Problems and improvements with respect to compile times. label Nov 8, 2022
@compiler-errors
Copy link
Member

Root-cause is likely that we're doing some expensive computation during typeck, but then suppressing it due to the fact that name resolution fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. I-compiletime Issue: Problems and improvements with respect to compile times.
Projects
None yet
Development

No branches or pull requests

3 participants