rust-lang / rust

Empowering everyone to build reliable and efficient software.

Home Page:https://www.rust-lang.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exponential compile time with broken huge nested enum

jruderman opened this issue · comments

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

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.