about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_driver/lib.rs35
-rw-r--r--src/librustc_interface/queries.rs64
2 files changed, 67 insertions, 32 deletions
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index f28119fb66a..b4dab397996 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -283,7 +283,7 @@ pub fn run_compiler(
             return sess.compile_status();
         }
 
-        compiler.enter(|queries| {
+        let linker = compiler.enter(|queries| {
             queries.parse()?;
 
             if let Some(ppm) = &sess.opts.pretty {
@@ -309,17 +309,20 @@ pub fn run_compiler(
                         compiler.output_file().as_ref().map(|p| &**p),
                     );
                 }
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             if callbacks.after_parsing(compiler) == Compilation::Stop {
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             if sess.opts.debugging_opts.parse_only ||
                sess.opts.debugging_opts.show_span.is_some() ||
                sess.opts.debugging_opts.ast_json_noexpand {
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             {
@@ -328,13 +331,15 @@ pub fn run_compiler(
                 // Lint plugins are registered; now we can process command line flags.
                 if sess.opts.describe_lints {
                     describe_lints(&sess, &lint_store, true);
-                    return sess.compile_status();
+                    sess.compile_status()?;
+                    return Ok(None);
                 }
             }
 
             queries.expansion()?;
             if callbacks.after_expansion(compiler) == Compilation::Stop {
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             queries.prepare_outputs()?;
@@ -342,14 +347,16 @@ pub fn run_compiler(
             if sess.opts.output_types.contains_key(&OutputType::DepInfo)
                 && sess.opts.output_types.len() == 1
             {
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             queries.global_ctxt()?;
 
             if sess.opts.debugging_opts.no_analysis ||
                sess.opts.debugging_opts.ast_json {
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             if sess.opts.debugging_opts.save_analysis {
@@ -381,7 +388,8 @@ pub fn run_compiler(
             queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?;
 
             if callbacks.after_analysis(compiler) == Compilation::Stop {
-                return sess.compile_status();
+                sess.compile_status()?;
+                return Ok(None);
             }
 
             if sess.opts.debugging_opts.save_analysis {
@@ -397,11 +405,14 @@ pub fn run_compiler(
                 sess.code_stats.print_type_sizes();
             }
 
-            queries.link()?;
-
-            Ok(())
+            let linker = queries.linker()?;
+            Ok(Some(linker))
         })?;
 
+        if let Some(linker) = linker {
+            linker.link()?
+        }
+
         if sess.opts.debugging_opts.perf_stats {
             sess.print_perf_stats();
         }
diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs
index 85bdd341f52..e91316ff477 100644
--- a/src/librustc_interface/queries.rs
+++ b/src/librustc_interface/queries.rs
@@ -81,7 +81,6 @@ pub struct Queries<'comp> {
     prepare_outputs: Query<OutputFilenames>,
     global_ctxt: Query<BoxedGlobalCtxt>,
     ongoing_codegen: Query<Box<dyn Any>>,
-    link: Query<()>,
 }
 
 impl<'comp> Queries<'comp> {
@@ -98,7 +97,6 @@ impl<'comp> Queries<'comp> {
             prepare_outputs: Default::default(),
             global_ctxt: Default::default(),
             ongoing_codegen: Default::default(),
-            link: Default::default(),
         }
     }
 
@@ -278,24 +276,43 @@ impl<'comp> Queries<'comp> {
         })
     }
 
-    pub fn link(&self) -> Result<&Query<()>> {
-        self.link.compute(|| {
-            let sess = self.session();
+    pub fn linker(self) -> Result<Linker> {
+        let dep_graph = self.dep_graph()?;
+        let prepare_outputs = self.prepare_outputs()?;
+        let ongoing_codegen = self.ongoing_codegen()?;
 
-            let ongoing_codegen = self.ongoing_codegen()?.take();
+        let sess = self.session().clone();
+        let codegen_backend = self.codegen_backend().clone();
 
-            self.codegen_backend().join_codegen_and_link(
-                ongoing_codegen,
-                sess,
-                &*self.dep_graph()?.peek(),
-                &*self.prepare_outputs()?.peek(),
-            ).map_err(|_| ErrorReported)?;
-
-            Ok(())
+        Ok(Linker {
+            sess,
+            dep_graph: dep_graph.take(),
+            prepare_outputs: prepare_outputs.take(),
+            ongoing_codegen: ongoing_codegen.take(),
+            codegen_backend,
         })
     }
 }
 
+pub struct Linker {
+    sess: Lrc<Session>,
+    dep_graph: DepGraph,
+    prepare_outputs: OutputFilenames,
+    ongoing_codegen: Box<dyn Any>,
+    codegen_backend: Lrc<Box<dyn CodegenBackend>>,
+}
+
+impl Linker {
+    pub fn link(self) -> Result<()> {
+        self.codegen_backend.join_codegen_and_link(
+            self.ongoing_codegen,
+            &self.sess,
+            &self.dep_graph,
+            &self.prepare_outputs,
+        ).map_err(|_| ErrorReported)
+    }
+}
+
 impl Compiler {
     // This method is different to all the other methods in `Compiler` because
     // it lacks a `Queries` entry. It's also not currently used. It does serve
@@ -303,10 +320,10 @@ impl Compiler {
     // between some passes. And see `rustc_driver::run_compiler` for a more
     // complex example.
     pub fn enter<'c, F, T>(&'c self, f: F) -> Result<T>
-        where F: for<'q> FnOnce(&'q Queries<'c>) -> Result<T>
+        where F: FnOnce(Queries<'c>) -> Result<T>
     {
         let queries = Queries::new(&self);
-        f(&queries)
+        f(queries)
     }
 
     // This method is different to all the other methods in `Compiler` because
@@ -315,13 +332,13 @@ impl Compiler {
     // between some passes. And see `rustc_driver::run_compiler` for a more
     // complex example.
     pub fn compile(&self) -> Result<()> {
-        self.enter(|queries| {
+        let linker = self.enter(|queries| {
             queries.prepare_outputs()?;
 
             if self.session().opts.output_types.contains_key(&OutputType::DepInfo)
                 && self.session().opts.output_types.len() == 1
             {
-                return Ok(())
+                return Ok(None)
             }
 
             queries.global_ctxt()?;
@@ -334,7 +351,14 @@ impl Compiler {
             // Drop GlobalCtxt after starting codegen to free memory.
             mem::drop(queries.global_ctxt()?.take());
 
-            queries.link().map(|_| ())
-        })
+            let linker = queries.linker()?;
+            Ok(Some(linker))
+        })?;
+
+        if let Some(linker) = linker {
+            linker.link()?
+        }
+
+        Ok(())
     }
 }