diff --git a/Cargo.toml b/Cargo.toml index 4413dab321..7580d140b5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,12 +17,6 @@ name = "miri" test = false # we have no unit tests doctest = false # and no doc tests -[[bin]] -name = "miri-rustc-tests" -test = false # we have no unit tests -doctest = false # and no doc tests -required-features = ["rustc_tests"] - [dependencies] getrandom = { version = "0.2", features = ["std"] } env_logger = "0.7.1" @@ -46,6 +40,3 @@ libc = "0.2" compiletest_rs = { version = "0.5", features = ["tmp"] } rustc_version = "0.2.3" colored = "2" - -[features] -rustc_tests = [] diff --git a/rust-version b/rust-version index c3173f6245..485cc2dd4b 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -828461b4b27c4a955587887936e54057efc5e2c1 +88b81970ba7a989a728b32039dd075dc206f1360 diff --git a/src/bin/miri-rustc-tests.rs b/src/bin/miri-rustc-tests.rs deleted file mode 100644 index cef71a9889..0000000000 --- a/src/bin/miri-rustc-tests.rs +++ /dev/null @@ -1,260 +0,0 @@ -#![feature(rustc_private)] - -extern crate rustc_middle; -extern crate rustc_driver; -extern crate rustc_hir; -extern crate rustc_interface; -extern crate rustc_span; - -use std::io; -use std::io::Write; -use std::path::Path; -use std::sync::{Arc, Mutex}; - -use rustc_middle::ty::TyCtxt; -use rustc_driver::Compilation; -use rustc_hir as hir; -use rustc_hir::def_id::LOCAL_CRATE; -use rustc_hir::itemlikevisit; -use rustc_interface::{interface, Queries}; - -struct MiriCompilerCalls { - /// whether we are building for the host - host_target: bool, -} - -impl rustc_driver::Callbacks for MiriCompilerCalls { - fn after_analysis<'tcx>( - &mut self, - compiler: &interface::Compiler, - queries: &'tcx Queries<'tcx>, - ) -> Compilation { - compiler.session().abort_if_errors(); - queries.global_ctxt().unwrap().peek_mut().enter(|tcx| { - if std::env::args().any(|arg| arg == "--test") { - struct Visitor<'tcx>(TyCtxt<'tcx>); - impl<'tcx, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'tcx> { - fn visit_item(&mut self, i: &'hir hir::Item) { - if let hir::ItemKind::Fn(.., body_id) = i.kind { - if i.attrs - .iter() - .any(|attr| self.0.sess.check_name(attr, rustc_span::symbol::sym::test)) - { - let config = miri::MiriConfig::default(); - let did = self.0.hir().body_owner_def_id(body_id).to_def_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) {} - } - tcx.hir().krate().visit_all_item_likes(&mut Visitor(tcx)); - } else if let Some((entry_def_id, _)) = tcx.entry_fn(LOCAL_CRATE) { - let config = miri::MiriConfig::default(); - miri::eval_main(tcx, entry_def_id.to_def_id(), config); - - compiler.session().abort_if_errors(); - } else { - println!("no main function found, assuming auxiliary build"); - } - }); - - // Continue execution on host target - if self.host_target { Compilation::Continue } else { Compilation::Stop } - } -} - -fn main() { - let path = option_env!("MIRI_RUSTC_TEST").map(String::from).unwrap_or_else(|| { - std::env::var("MIRI_RUSTC_TEST") - .expect("need to set MIRI_RUSTC_TEST to path of rustc tests") - }); - - let mut mir_not_found = Vec::new(); - let mut crate_not_found = Vec::new(); - let mut success = 0; - let mut failed = Vec::new(); - let mut c_abi_fns = Vec::new(); - let mut abi = Vec::new(); - let mut unsupported = Vec::new(); - let mut unimplemented_intrinsic = Vec::new(); - let mut limits = Vec::new(); - let mut files: Vec<_> = std::fs::read_dir(path).unwrap().collect(); - while let Some(file) = files.pop() { - let file = file.unwrap(); - let path = file.path(); - if file.metadata().unwrap().is_dir() { - if !path.to_str().unwrap().ends_with("auxiliary") { - // add subdirs recursively - files.extend(std::fs::read_dir(path).unwrap()); - } - continue; - } - if !file.metadata().unwrap().is_file() || !path.to_str().unwrap().ends_with(".rs") { - continue; - } - let stderr = std::io::stderr(); - write!(stderr.lock(), "test [miri-pass] {} ... ", path.display()).unwrap(); - let mut host_target = false; - let mut args: Vec = std::env::args() - .filter(|arg| { - if arg == "--miri_host_target" { - host_target = true; - false // remove the flag, rustc doesn't know it - } else { - true - } - }) - .collect(); - args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string)); - // file to process - args.push(path.display().to_string()); - - let sysroot_flag = String::from("--sysroot"); - if !args.contains(&sysroot_flag) { - args.push(sysroot_flag); - args.push( - Path::new(&std::env::var("HOME").unwrap()) - .join(".xargo") - .join("HOST") - .display() - .to_string(), - ); - } - - // A threadsafe buffer for writing. - #[derive(Default, Clone)] - struct BufWriter(Arc>>); - - impl Write for BufWriter { - fn write(&mut self, buf: &[u8]) -> io::Result { - self.0.lock().unwrap().write(buf) - } - fn flush(&mut self) -> io::Result<()> { - self.0.lock().unwrap().flush() - } - } - let buf = BufWriter::default(); - let output = buf.clone(); - let result = std::panic::catch_unwind(|| { - let mut callbacks = MiriCompilerCalls { host_target }; - let mut run = rustc_driver::RunCompiler::new(&args, &mut callbacks); - run.set_emitter(Some(Box::new(buf))); - let _ = run.run(); - }); - - match result { - Ok(()) => { - success += 1; - writeln!(stderr.lock(), "ok").unwrap() - } - Err(_) => { - let output = output.0.lock().unwrap(); - let output_err = std::str::from_utf8(&output).unwrap(); - if let Some(text) = output_err.splitn(2, "no mir for `").nth(1) { - let end = text.find('`').unwrap(); - mir_not_found.push(text[..end].to_string()); - writeln!(stderr.lock(), "NO MIR FOR `{}`", &text[..end]).unwrap(); - } else if let Some(text) = output_err.splitn(2, "can't find crate for `").nth(1) { - let end = text.find('`').unwrap(); - crate_not_found.push(text[..end].to_string()); - writeln!(stderr.lock(), "CAN'T FIND CRATE FOR `{}`", &text[..end]).unwrap(); - } else { - for text in output_err.split("error: ").skip(1) { - let end = text.find('\n').unwrap_or(text.len()); - let c_abi = "can't call C ABI function: "; - let unimplemented_intrinsic_s = "unimplemented intrinsic: "; - let unsupported_s = "miri does not support "; - let abi_s = "can't handle function with "; - let limit_s = "reached the configured maximum "; - if text.starts_with(c_abi) { - c_abi_fns.push(text[c_abi.len()..end].to_string()); - } else if text.starts_with(unimplemented_intrinsic_s) { - unimplemented_intrinsic - .push(text[unimplemented_intrinsic_s.len()..end].to_string()); - } else if text.starts_with(unsupported_s) { - unsupported.push(text[unsupported_s.len()..end].to_string()); - } else if text.starts_with(abi_s) { - abi.push(text[abi_s.len()..end].to_string()); - } else if text.starts_with(limit_s) { - limits.push(text[limit_s.len()..end].to_string()); - } else if text.find("aborting").is_none() { - failed.push(text[..end].to_string()); - } - } - writeln!(stderr.lock(), "stderr: \n {}", output_err).unwrap(); - } - } - } - } - let stderr = std::io::stderr(); - let mut stderr = stderr.lock(); - writeln!( - stderr, - "{} success, {} no mir, {} crate not found, {} failed, {} C fn, {} ABI, {} unsupported, {} intrinsic", - success, - mir_not_found.len(), - crate_not_found.len(), - failed.len(), - c_abi_fns.len(), - abi.len(), - unsupported.len(), - unimplemented_intrinsic.len() - ) - .unwrap(); - writeln!(stderr, "# The \"other reasons\" errors").unwrap(); - writeln!(stderr, "(sorted, deduplicated)").unwrap(); - print_vec(&mut stderr, failed); - - writeln!(stderr, "# can't call C ABI function").unwrap(); - print_vec(&mut stderr, c_abi_fns); - - writeln!(stderr, "# unsupported ABI").unwrap(); - print_vec(&mut stderr, abi); - - writeln!(stderr, "# unsupported").unwrap(); - print_vec(&mut stderr, unsupported); - - writeln!(stderr, "# unimplemented intrinsics").unwrap(); - print_vec(&mut stderr, unimplemented_intrinsic); - - writeln!(stderr, "# mir not found").unwrap(); - print_vec(&mut stderr, mir_not_found); - - writeln!(stderr, "# crate not found").unwrap(); - print_vec(&mut stderr, crate_not_found); -} - -fn print_vec(stderr: &mut W, v: Vec) { - writeln!(stderr, "```").unwrap(); - for (n, s) in vec_to_hist(v).into_iter().rev() { - writeln!(stderr, "{:4} {}", n, s).unwrap(); - } - writeln!(stderr, "```").unwrap(); -} - -fn vec_to_hist(mut v: Vec) -> Vec<(usize, T)> { - v.sort(); - let mut v = v.into_iter(); - let mut result = Vec::new(); - let mut current = v.next(); - 'outer: while let Some(current_val) = current { - let mut n = 1; - for next in &mut v { - if next == current_val { - n += 1; - } else { - result.push((n, current_val)); - current = Some(next); - continue 'outer; - } - } - result.push((n, current_val)); - break; - } - result.sort(); - result -}