diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 619a1b67f277e42f853ff83c1fa09a0f038bbee7..7fd4e3643be57a429992a7e4c02d3b595eb213ce 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -116,8 +116,16 @@ pub fn compile_input(sess: &Session, let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess); let id = link::find_crate_name(Some(sess), &krate.attrs, input); let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = { - let make_glob_map = control.make_glob_map; - phase_2_configure_and_expand(sess, &cstore, krate, &id, addl_plugins, make_glob_map)? + phase_2_configure_and_expand( + sess, &cstore, krate, &id, addl_plugins, control.make_glob_map, + |expanded_crate| { + let mut state = CompileState::state_after_expand( + input, sess, outdir, output, &cstore, expanded_crate, &id, + ); + controller_entry_point!(after_expand, sess, state, Ok(())); + Ok(()) + } + )? }; write_out_deps(sess, &outputs, &id); @@ -262,6 +270,7 @@ pub fn source_name(input: &Input) -> String { /// Expect more entry points to be added in the future. pub struct CompileController<'a> { pub after_parse: PhaseController<'a>, + pub after_expand: PhaseController<'a>, pub after_hir_lowering: PhaseController<'a>, pub after_analysis: PhaseController<'a>, pub after_llvm: PhaseController<'a>, @@ -273,6 +282,7 @@ impl<'a> CompileController<'a> { pub fn basic() -> CompileController<'a> { CompileController { after_parse: PhaseController::basic(), + after_expand: PhaseController::basic(), after_hir_lowering: PhaseController::basic(), after_analysis: PhaseController::basic(), after_llvm: PhaseController::basic(), @@ -363,6 +373,23 @@ fn state_after_parse(input: &'a Input, } } + fn state_after_expand(input: &'a Input, + session: &'ast Session, + out_dir: &'a Option, + out_file: &'a Option, + cstore: &'a CStore, + expanded_crate: &'a ast::Crate, + crate_name: &'a str) + -> CompileState<'a, 'b, 'ast, 'tcx> { + CompileState { + crate_name: Some(crate_name), + cstore: Some(cstore), + expanded_crate: Some(expanded_crate), + out_file: out_file.as_ref().map(|s| &**s), + ..CompileState::empty(input, session, out_dir) + } + } + fn state_after_hir_lowering(input: &'a Input, session: &'ast Session, out_dir: &'a Option, @@ -496,13 +523,16 @@ pub struct ExpansionResult<'a> { /// standard library and prelude, and name resolution. /// /// Returns `None` if we're aborting after handling -W help. -pub fn phase_2_configure_and_expand<'a>(sess: &Session, - cstore: &CStore, - mut krate: ast::Crate, - crate_name: &'a str, - addl_plugins: Option>, - make_glob_map: MakeGlobMap) - -> Result, usize> { +pub fn phase_2_configure_and_expand<'a, F>(sess: &Session, + cstore: &CStore, + mut krate: ast::Crate, + crate_name: &'a str, + addl_plugins: Option>, + make_glob_map: MakeGlobMap, + after_expand: F) + -> Result, usize> + where F: FnOnce(&ast::Crate) -> CompileResult, +{ let time_passes = sess.time_passes(); // strip before anything else because crate metadata may use #[cfg_attr] @@ -685,9 +715,23 @@ pub fn phase_2_configure_and_expand<'a>(sess: &Session, "AST validation", || ast_validation::check_crate(sess, &krate)); - time(sess.time_passes(), "name resolution", || { + time(sess.time_passes(), "name resolution", || -> CompileResult { + // Currently, we ignore the name resolution data structures for the purposes of dependency + // tracking. Instead we will run name resolution and include its output in the hash of each + // item, much like we do for macro expansion. In other words, the hash reflects not just + // its contents but the results of name resolution on those contents. Hopefully we'll push + // this back at some point. + let _ignore = sess.dep_graph.in_ignore(); + resolver.build_reduced_graph(&krate); + resolver.resolve_imports(); + + // Since import resolution will eventually happen in expansion, + // don't perform `after_expand` until after import resolution. + after_expand(&krate)?; + resolver.resolve_crate(&krate); - }); + Ok(()) + })?; // Lower ast -> hir. let hir_forest = time(sess.time_passes(), "lowering ast -> hir", || { diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 0f5977cf06618822a0438fc935845a2502568ac3..15a0ab0f284b3efdde3be345078029b4be4446af 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -116,9 +116,11 @@ fn test_env(source_string: &str, input: source_string.to_string(), }; let krate = driver::phase_1_parse_input(&sess, krate_config, &input).unwrap(); - let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = - driver::phase_2_configure_and_expand(&sess, &cstore, krate, "test", None, MakeGlobMap::No) - .expect("phase 2 aborted"); + let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = { + driver::phase_2_configure_and_expand( + &sess, &cstore, krate, "test", None, MakeGlobMap::No, |_| Ok(()), + ).expect("phase 2 aborted") + }; let _ignore = dep_graph.in_ignore(); let arenas = ty::CtxtArenas::new(); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index ed400af66855a66145924a9cf66ac240e542e37b..66b0d663424aa829a95c673de86b76e27b63ae8e 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1167,18 +1167,6 @@ pub fn arenas() -> ResolverArenas<'a> { /// Entry point to crate resolution. pub fn resolve_crate(&mut self, krate: &Crate) { - // Currently, we ignore the name resolution data structures for - // the purposes of dependency tracking. Instead we will run name - // resolution and include its output in the hash of each item, - // much like we do for macro expansion. In other words, the hash - // reflects not just its contents but the results of name - // resolution on those contents. Hopefully we'll push this back at - // some point. - let _ignore = self.session.dep_graph.in_ignore(); - - self.build_reduced_graph(krate); - resolve_imports::resolve_imports(self); - self.current_module = self.graph_root; visit::walk_crate(self, krate); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index cb308f91204046fae6b06b7a73eafbce7e7e1a8e..16a59fbb800024afcd24c43de94a8b15307da684 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -30,6 +30,12 @@ use std::cell::{Cell, RefCell}; +impl<'a> Resolver<'a> { + pub fn resolve_imports(&mut self) { + ImportResolver { resolver: self }.resolve_imports(); + } +} + /// Contains data for specific types of import directives. #[derive(Clone, Debug)] pub enum ImportDirectiveSubclass { @@ -722,8 +728,3 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St GlobImport { .. } => "*".to_string(), } } - -pub fn resolve_imports(resolver: &mut Resolver) { - let mut import_resolver = ImportResolver { resolver: resolver }; - import_resolver.resolve_imports(); -} diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index f4da8167ea28640fe4f9c8b64a5f9ee9303d267e..85ea94e02e8d794014a13263b2d9db970337abe6 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -149,9 +149,9 @@ pub fn run_core(search_paths: SearchPaths, let name = link::find_crate_name(Some(&sess), &krate.attrs, &input); let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = { - let make_glob_map = resolve::MakeGlobMap::No; - driver::phase_2_configure_and_expand(&sess, &cstore, krate, &name, None, make_glob_map) - .expect("phase_2_configure_and_expand aborted in rustdoc!") + driver::phase_2_configure_and_expand( + &sess, &cstore, krate, &name, None, resolve::MakeGlobMap::No, |_| Ok(()), + ).expect("phase_2_configure_and_expand aborted in rustdoc!") }; let arenas = ty::CtxtArenas::new(); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 95d02d6ce4bee33135aae9a295aaf593965bbd6d..e3bc8037d13b67b0395baeb7560bb6b964a8c283 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -95,9 +95,9 @@ pub fn run(input: &str, cfg.extend(config::parse_cfgspecs(cfgs.clone())); let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input)); let driver::ExpansionResult { defs, mut hir_forest, .. } = { - let make_glob_map = MakeGlobMap::No; - phase_2_configure_and_expand(&sess, &cstore, krate, "rustdoc-test", None, make_glob_map) - .expect("phase_2_configure_and_expand aborted in rustdoc!") + phase_2_configure_and_expand( + &sess, &cstore, krate, "rustdoc-test", None, MakeGlobMap::No, |_| Ok(()) + ).expect("phase_2_configure_and_expand aborted in rustdoc!") }; let dep_graph = DepGraph::new(false); diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index a94b2a85c7754046716f305773b3f514a7df9aa0..21e1463b6ef955efdf9929e42acf2f4944c7deaa 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -241,8 +241,9 @@ fn compile_program(input: &str, sysroot: PathBuf) let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input)); let driver::ExpansionResult { defs, analysis, resolutions, mut hir_forest, .. } = { - driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None, MakeGlobMap::No) - .expect("phase_2 returned `None`") + driver::phase_2_configure_and_expand( + &sess, &cstore, krate, &id, None, MakeGlobMap::No, |_| Ok(()), + ).expect("phase_2 returned `None`") }; let arenas = ty::CtxtArenas::new();