From 7d142ecf75cc347213502311253cd41f5d87dfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Fri, 1 Feb 2019 23:26:42 +0100 Subject: [PATCH] Use the new rustc interface --- benches/helpers/miri_helper.rs | 58 +++++++------- src/bin/miri-rustc-tests.rs | 128 ++++++++++-------------------- src/bin/miri.rs | 138 ++++++++------------------------- 3 files changed, 105 insertions(+), 219 deletions(-) diff --git a/benches/helpers/miri_helper.rs b/benches/helpers/miri_helper.rs index 404fe7ae9150..3e3c3a53f754 100644 --- a/benches/helpers/miri_helper.rs +++ b/benches/helpers/miri_helper.rs @@ -2,18 +2,39 @@ extern crate getopts; extern crate miri; extern crate rustc; extern crate rustc_driver; +extern crate rustc_interface; extern crate test; -use rustc_driver::{driver, Compilation}; +use self::miri::eval_main; use rustc::hir::def_id::LOCAL_CRATE; -use std::cell::RefCell; -use std::rc::Rc; - -use miri::{MiriConfig, eval_main}; - +use rustc_interface::interface; use crate::test::Bencher; -pub struct MiriCompilerCalls<'a>(Rc>); +struct MiriCompilerCalls<'a> { + bencher: &'a mut Bencher, +} + +impl rustc_driver::Callbacks for MiriCompilerCalls<'_> { + fn after_analysis(&mut self, compiler: &interface::Compiler<'_>) -> bool { + compiler.session().abort_if_errors(); + + compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| { + let (entry_def_id, _) = tcx.entry_fn(LOCAL_CRATE).expect( + "no main or start function found", + ); + + self.bencher.iter(|| { + let config = MiriConfig { validate: true, args: vec![] }; + eval_main(tcx, entry_def_id, config); + }); + }); + + compiler.session().abort_if_errors(); + + // Don't continue execution + false + } +} fn find_sysroot() -> String { // Taken from https://github.com/Manishearth/rust-clippy/pull/911. @@ -38,26 +59,5 @@ pub fn run(filename: &str, bencher: &mut Bencher) { "--sysroot".to_string(), find_sysroot(), ]; - let bencher = RefCell::new(bencher); - - let mut control = driver::CompileController::basic(); - - control.after_analysis.stop = Compilation::Stop; - control.after_analysis.callback = Box::new(move |state| { - state.session.abort_if_errors(); - - let tcx = state.tcx.unwrap(); - let (entry_def_id, _) = tcx.entry_fn(LOCAL_CRATE).expect( - "no main or start function found", - ); - - bencher.borrow_mut().iter(|| { - let config = MiriConfig { validate: true, args: vec![] }; - eval_main(tcx, entry_def_id, config); - }); - - state.session.abort_if_errors(); - }); - - rustc_driver::run_compiler(args, Box::new(control), None, None); + rustc_driver::run_compiler(args, &mut MiriCompilerCalls { bencher }, None, None); } diff --git a/src/bin/miri-rustc-tests.rs b/src/bin/miri-rustc-tests.rs index 3a70577cb7f2..cab8d845fc0d 100644 --- a/src/bin/miri-rustc-tests.rs +++ b/src/bin/miri-rustc-tests.rs @@ -6,6 +6,7 @@ extern crate rustc_metadata; extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_codegen_utils; +extern crate rustc_interface; extern crate syntax; use std::path::{PathBuf, Path}; @@ -15,12 +16,10 @@ use std::io; use rustc::session::Session; +use rustc_interface::interface; use rustc_metadata::cstore::CStore; -use rustc_driver::{Compilation, CompilerCalls, RustcDefaultCalls}; -use rustc_driver::driver::{CompileState, CompileController}; use rustc::session::config::{self, Input, ErrorOutputType}; use rustc::hir::{self, itemlikevisit}; -use rustc_codegen_utils::codegen_backend::CodegenBackend; use rustc::ty::TyCtxt; use syntax::ast; use rustc::hir::def_id::LOCAL_CRATE; @@ -28,93 +27,55 @@ use rustc::hir::def_id::LOCAL_CRATE; use miri::MiriConfig; struct MiriCompilerCalls { - default: Box, /// whether we are building for the host host_target: bool, } -impl<'a> CompilerCalls<'a> for MiriCompilerCalls { - fn early_callback( - &mut self, - matches: &getopts::Matches, - sopts: &config::Options, - cfg: &ast::CrateConfig, - descriptions: &rustc_errors::registry::Registry, - output: ErrorOutputType - ) -> Compilation { - self.default.early_callback(matches, sopts, cfg, descriptions, output) - } - fn no_input( - &mut self, - matches: &getopts::Matches, - sopts: &config::Options, - cfg: &ast::CrateConfig, - odir: &Option, - ofile: &Option, - descriptions: &rustc_errors::registry::Registry - ) -> Option<(Input, Option)> { - self.default.no_input(matches, sopts, cfg, odir, ofile, descriptions) - } - fn late_callback( - &mut self, - trans: &CodegenBackend, - matches: &getopts::Matches, - sess: &Session, - cstore: &CStore, - input: &Input, - odir: &Option, - ofile: &Option, - ) -> Compilation { - self.default.late_callback(trans, matches, sess, cstore, input, odir, ofile) - } - fn build_controller(self: Box, sess: &Session, matches: &getopts::Matches) -> CompileController<'a> { - let this = *self; - let mut control = this.default.build_controller(sess, matches); - control.after_hir_lowering.callback = Box::new(after_hir_lowering); - control.after_analysis.callback = Box::new(after_analysis); - if !this.host_target { - // only fully compile targets on the host - control.after_analysis.stop = Compilation::Stop; - } - control - } -} +impl rustc_driver::Callbacks for MiriCompilerCalls { + fn after_parsing(&mut self, compiler: &interface::Compiler<'_>) -> bool { + let attr = ( + String::from("miri"), + syntax::feature_gate::AttributeType::Whitelisted, + ); + compiler.session().plugin_attributes.borrow_mut().push(attr); -fn after_hir_lowering(state: &mut CompileState) { - let attr = (String::from("miri"), syntax::feature_gate::AttributeType::Whitelisted); - state.session.plugin_attributes.borrow_mut().push(attr); -} + // Continue execution + true + } -fn after_analysis<'a, 'tcx>(state: &mut CompileState<'a, 'tcx>) { - state.session.abort_if_errors(); - - let tcx = state.tcx.unwrap(); - - if std::env::args().any(|arg| arg == "--test") { - struct Visitor<'a, 'tcx: 'a>(TyCtxt<'a, 'tcx, 'tcx>, &'a CompileState<'a, 'tcx>); - impl<'a, 'tcx: 'a, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'a, 'tcx> { - fn visit_item(&mut self, i: &'hir hir::Item) { - if let hir::ItemKind::Fn(.., body_id) = i.node { - if i.attrs.iter().any(|attr| attr.name() == "test") { - let config = MiriConfig { validate: true, args: vec![] }; - let did = self.0.hir().body_owner_def_id(body_id); - println!("running test: {}", self.0.def_path_debug_str(did)); - miri::eval_main(self.0, did, config); - self.1.session.abort_if_errors(); + fn after_analysis(&mut self, compiler: &interface::Compiler<'_>) -> bool { + compiler.session().abort_if_errors(); + compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| { + if std::env::args().any(|arg| arg == "--test") { + struct Visitor<'a, 'tcx: 'a>(TyCtxt<'a, 'tcx, 'tcx>); + impl<'a, 'tcx: 'a, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'a, 'tcx> { + fn visit_item(&mut self, i: &'hir hir::Item) { + if let hir::ItemKind::Fn(.., body_id) = i.node { + if i.attrs.iter().any(|attr| attr.name() == "test") { + let config = MiriConfig { validate: true, args: vec![] }; + let did = self.0.hir().body_owner_def_id(body_id); + println!("running test: {}", self.0.def_path_debug_str(did)); + miri::eval_main(self.0, did, config); + self.0.sess.abort_if_errors(); + } + } } + fn visit_trait_item(&mut self, _trait_item: &'hir hir::TraitItem) {} + fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {} } - } - fn visit_trait_item(&mut self, _trait_item: &'hir hir::TraitItem) {} - fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {} - } - state.hir_crate.unwrap().visit_all_item_likes(&mut Visitor(tcx, state)); - } else if let Some((entry_def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { - let config = MiriConfig { validate: true, args: vec![] }; - miri::eval_main(tcx, entry_def_id, config); + tcx.hir().krate().visit_all_item_likes(&mut Visitor(tcx)); + } else if let Some((entry_def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { + let config = MiriConfig { validate: true, args: vec![] }; + miri::eval_main(tcx, entry_def_id, config); - state.session.abort_if_errors(); - } else { - println!("no main function found, assuming auxiliary build"); + compiler.session().abort_if_errors(); + } else { + println!("no main function found, assuming auxiliary build"); + } + }); + + // Continue execution on host target + self.host_target } } @@ -185,10 +146,7 @@ fn main() { let buf = BufWriter::default(); let output = buf.clone(); let result = std::panic::catch_unwind(|| { - rustc_driver::run_compiler(&args, Box::new(MiriCompilerCalls { - default: Box::new(RustcDefaultCalls), - host_target, - }), None, Some(Box::new(buf))); + rustc_driver::run_compiler(&args, &mut MiriCompilerCalls { host_target }, None, Some(Box::new(buf))); }); match result { diff --git a/src/bin/miri.rs b/src/bin/miri.rs index c1cad6edc0ab..27e52d5f1a06 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -11,115 +11,46 @@ extern crate rustc_metadata; extern crate rustc_driver; extern crate rustc_errors; extern crate rustc_codegen_utils; +extern crate rustc_interface; extern crate syntax; -use std::path::PathBuf; use std::str::FromStr; use std::env; -use miri::MiriConfig; -use rustc::session::Session; -use rustc_metadata::cstore::CStore; -use rustc_driver::{Compilation, CompilerCalls, RustcDefaultCalls}; -use rustc_driver::driver::{CompileState, CompileController}; -use rustc::session::config::{self, Input, ErrorOutputType}; -use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_interface::interface; use rustc::hir::def_id::LOCAL_CRATE; -use syntax::ast; struct MiriCompilerCalls { - default: Box, - miri_config: MiriConfig, + miri_config: miri::MiriConfig, } -impl<'a> CompilerCalls<'a> for MiriCompilerCalls { - fn early_callback( - &mut self, - matches: &getopts::Matches, - sopts: &config::Options, - cfg: &ast::CrateConfig, - descriptions: &rustc_errors::registry::Registry, - output: ErrorOutputType, - ) -> Compilation { - self.default.early_callback( - matches, - sopts, - cfg, - descriptions, - output, - ) +impl rustc_driver::Callbacks for MiriCompilerCalls { + fn after_parsing(&mut self, compiler: &interface::Compiler) -> bool { + let attr = ( + String::from("miri"), + syntax::feature_gate::AttributeType::Whitelisted, + ); + compiler.session().plugin_attributes.borrow_mut().push(attr); + + // Continue execution + true } - fn no_input( - &mut self, - matches: &getopts::Matches, - sopts: &config::Options, - cfg: &ast::CrateConfig, - odir: &Option, - ofile: &Option, - descriptions: &rustc_errors::registry::Registry, - ) -> Option<(Input, Option)> { - self.default.no_input( - matches, - sopts, - cfg, - odir, - ofile, - descriptions, - ) + + fn after_analysis(&mut self, compiler: &interface::Compiler) -> bool { + init_late_loggers(); + compiler.session().abort_if_errors(); + + compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| { + let (entry_def_id, _) = tcx.entry_fn(LOCAL_CRATE).expect("no main function found!"); + + miri::eval_main(tcx, entry_def_id, self.miri_config.clone()); + }); + + compiler.session().abort_if_errors(); + + // Don't continue execution + false } - fn late_callback( - &mut self, - codegen_backend: &CodegenBackend, - matches: &getopts::Matches, - sess: &Session, - cstore: &CStore, - input: &Input, - odir: &Option, - ofile: &Option, - ) -> Compilation { - // Called *before* `build_controller`. Add filename to `miri` arguments. - self.miri_config.args.insert(0, input.filestem().to_string()); - self.default.late_callback(codegen_backend, matches, sess, cstore, input, odir, ofile) - } - fn build_controller( - self: Box, - sess: &Session, - matches: &getopts::Matches, - ) -> CompileController<'a> { - let this = *self; - let mut control = this.default.build_controller(sess, matches); - control.after_hir_lowering.callback = Box::new(after_hir_lowering); - let miri_config = this.miri_config; - control.after_analysis.callback = - Box::new(move |state| after_analysis(state, miri_config.clone())); - control.after_analysis.stop = Compilation::Stop; - control - } -} - -fn after_hir_lowering(state: &mut CompileState) { - let attr = ( - String::from("miri"), - syntax::feature_gate::AttributeType::Whitelisted, - ); - state.session.plugin_attributes.borrow_mut().push(attr); -} - -fn after_analysis<'a, 'tcx>( - state: &mut CompileState<'a, 'tcx>, - miri_config: MiriConfig, -) { - init_late_loggers(); - state.session.abort_if_errors(); - - let tcx = state.tcx.unwrap(); - - - let (entry_def_id, _) = tcx.entry_fn(LOCAL_CRATE).expect("no main function found!"); - - miri::eval_main(tcx, entry_def_id, miri_config); - - state.session.abort_if_errors(); } fn init_early_loggers() { @@ -228,12 +159,9 @@ fn main() { debug!("rustc arguments: {:?}", rustc_args); debug!("miri arguments: {:?}", miri_args); - let miri_config = MiriConfig { validate, args: miri_args }; - let result = rustc_driver::run(move || { - rustc_driver::run_compiler(&rustc_args, Box::new(MiriCompilerCalls { - default: Box::new(RustcDefaultCalls), - miri_config, - }), None, None) - }); - std::process::exit(result as i32); + let miri_config = miri::MiriConfig { validate, args: miri_args }; + let result = rustc_driver::report_ices_to_stderr_if_any(move || { + rustc_driver::run_compiler(&rustc_args, &mut MiriCompilerCalls { miri_config }, None, None) + }).and_then(|result| result); + std::process::exit(result.is_err() as i32); }