--- /dev/null
+[root]
+name = "rustc_tests"
+version = "0.1.0"
+dependencies = [
+ "miri 0.1.0",
+]
+
+[[package]]
+name = "aho-corasick"
+version = "0.5.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "byteorder"
+version = "1.1.0"
+source = "git+https://github.com/BurntSushi/byteorder#88f0b9851e9824d54248b862b20fe28415a30ec0"
+
+[[package]]
+name = "cargo_metadata"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "dtoa"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "env_logger"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "itoa"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "kernel32-sys"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "lazy_static"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "libc"
+version = "0.2.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "log"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "log_settings"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "memchr"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "miri"
+version = "0.1.0"
+dependencies = [
+ "byteorder 1.1.0 (git+https://github.com/BurntSushi/byteorder)",
+ "cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "quote"
+version = "0.3.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "regex"
+version = "0.1.80"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_derive_internals"
+version = "0.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "syn"
+version = "0.11.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synom"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "thread-id"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "thread_local"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "utf8-ranges"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "winapi-build"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[metadata]
+"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
+"checksum byteorder 1.1.0 (git+https://github.com/BurntSushi/byteorder)" = "<none>"
+"checksum cargo_metadata 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "be1057b8462184f634c3a208ee35b0f935cfd94b694b26deadccd98732088d7b"
+"checksum dtoa 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "80c8b71fd71146990a9742fc06dcbbde19161a267e0ad4e572c35162f4578c90"
+"checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
+"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
+"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
+"checksum lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3b37545ab726dd833ec6420aaba8231c5b320814b9029ad585555d2a03e94fbf"
+"checksum libc 0.2.26 (registry+https://github.com/rust-lang/crates.io-index)" = "30885bcb161cf67054244d10d4a7f4835ffd58773bc72e07d35fecf472295503"
+"checksum log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "880f77541efa6e5cc74e76910c9884d9859683118839d6a1dc3b11e63512565b"
+"checksum log_settings 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3d382732ea0fbc09790c4899db3255bdea0fc78b54bf234bd18a63bb603915b6"
+"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
+"checksum num-traits 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "99843c856d68d8b4313b03a17e33c4bb42ae8f6610ea81b28abe076ac721b9b0"
+"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
+"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
+"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
+"checksum serde 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "433d7d9f8530d5a939ad5e0e72a6243d2e42a24804f70bf592c679363dcacb2f"
+"checksum serde_derive 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "7b707cf0d4cab852084f573058def08879bb467fda89d99052485e7d00edd624"
+"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
+"checksum serde_json 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "48b04779552e92037212c3615370f6bd57a40ebba7f20e554ff9f55e41a69a7b"
+"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
+"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
+"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
+"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
+"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
+"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
+"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
+"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
--- /dev/null
+[package]
+name = "rustc_tests"
+version = "0.1.0"
+authors = ["Oliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>"]
+
+[dependencies]
+miri = { path = ".." }
--- /dev/null
+#![feature(rustc_private, i128_type)]
+extern crate miri;
+extern crate getopts;
+extern crate rustc;
+extern crate rustc_driver;
+extern crate rustc_errors;
+extern crate syntax;
+
+use std::path::{PathBuf, Path};
+use std::io::Write;
+use std::sync::{Mutex, Arc};
+use std::io;
+
+
+use rustc::session::Session;
+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::ty::TyCtxt;
+use syntax::ast;
+
+struct MiriCompilerCalls(RustcDefaultCalls);
+
+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.0.early_callback(matches, sopts, cfg, descriptions, output)
+ }
+ fn no_input(
+ &mut self,
+ matches: &getopts::Matches,
+ sopts: &config::Options,
+ cfg: &ast::CrateConfig,
+ odir: &Option<PathBuf>,
+ ofile: &Option<PathBuf>,
+ descriptions: &rustc_errors::registry::Registry
+ ) -> Option<(Input, Option<PathBuf>)> {
+ self.0.no_input(matches, sopts, cfg, odir, ofile, descriptions)
+ }
+ fn late_callback(
+ &mut self,
+ matches: &getopts::Matches,
+ sess: &Session,
+ input: &Input,
+ odir: &Option<PathBuf>,
+ ofile: &Option<PathBuf>
+ ) -> Compilation {
+ self.0.late_callback(matches, sess, input, odir, ofile)
+ }
+ fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> CompileController<'a> {
+ let mut control = self.0.build_controller(sess, matches);
+ control.after_hir_lowering.callback = Box::new(after_hir_lowering);
+ control.after_analysis.callback = Box::new(after_analysis);
+ if std::env::var("MIRI_HOST_TARGET") != Ok("yes".to_owned()) {
+ // only fully compile targets on the host
+ 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>) {
+ state.session.abort_if_errors();
+
+ let tcx = state.tcx.unwrap();
+ let limits = Default::default();
+
+ if std::env::args().any(|arg| arg == "--test") {
+ struct Visitor<'a, 'tcx: 'a>(miri::ResourceLimits, 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::Item_::ItemFn(_, _, _, _, _, body_id) = i.node {
+ if i.attrs.iter().any(|attr| attr.name().map_or(false, |n| n == "test")) {
+ let did = self.1.hir.body_owner_def_id(body_id);
+ println!("running test: {}", self.1.hir.def_path(did).to_string(self.1));
+ miri::eval_main(self.1, did, None, self.0);
+ self.2.session.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) {}
+ }
+ state.hir_crate.unwrap().visit_all_item_likes(&mut Visitor(limits, tcx, state));
+ } else if let Some((entry_node_id, _)) = *state.session.entry_fn.borrow() {
+ let entry_def_id = tcx.hir.local_def_id(entry_node_id);
+ let start_wrapper = tcx.lang_items.start_fn().and_then(|start_fn|
+ if tcx.is_mir_available(start_fn) { Some(start_fn) } else { None });
+ miri::eval_main(tcx, entry_def_id, start_wrapper, limits);
+
+ state.session.abort_if_errors();
+ } else {
+ println!("no main function found, assuming auxiliary build");
+ }
+}
+
+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 args: Vec<String> = std::env::args().collect();
+ // 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());
+ }
+
+ // we run the optimization passes inside miri
+ // if we ran them twice we'd get funny failures due to borrowck ElaborateDrops only working on
+ // unoptimized MIR
+ // FIXME: add an after-mir-passes hook to rustc driver
+ args.push("-Zmir-opt-level=0".to_owned());
+ // for auxilary builds in unit tests
+ args.push("-Zalways-encode-mir".to_owned());
+
+ // A threadsafe buffer for writing.
+ #[derive(Default, Clone)]
+ struct BufWriter(Arc<Mutex<Vec<u8>>>);
+
+ impl Write for BufWriter {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ 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(|| {
+ rustc_driver::run_compiler(&args, &mut MiriCompilerCalls(RustcDefaultCalls), None, Some(Box::new(buf)));
+ });
+
+ 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();:{MetaItemKind, NestedMetaItemKind, self};
+ 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<W: std::io::Write>(stderr: &mut W, v: Vec<String>) {
+ 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<T: PartialEq + Ord>(mut v: Vec<T>) -> 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
+}
String::from(host)
}
-#[test]
-fn rustc_test() {
- if let Ok(path) = std::env::var("MIRI_RUSTC_TEST") {
- let sysroot = get_sysroot();
- let host = get_host();
-
- 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 cmd = std::process::Command::new("target/debug/miri");
- cmd.arg(path);
- let libs = Path::new(&sysroot).join("lib");
- let sysroot = libs.join("rustlib").join(&host).join("lib");
- let paths = std::env::join_paths(&[libs, sysroot]).unwrap();
- cmd.env(compiletest::procsrv::dylib_env_var(), paths);
- cmd.env("MIRI_SYSROOT", Path::new(&std::env::var("HOME").unwrap()).join(".xargo").join("HOST"));
-
- match cmd.output() {
- Ok(ref output) if output.status.success() => {
- success += 1;
- writeln!(stderr.lock(), "ok").unwrap()
- },
- Ok(output) => {
- let output_err = std::str::from_utf8(&output.stderr).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(), "FAILED with exit code {:?}", output.status.code()).unwrap();
- writeln!(stderr.lock(), "stdout: \n {}", std::str::from_utf8(&output.stdout).unwrap()).unwrap();
- writeln!(stderr.lock(), "stderr: \n {}", output_err).unwrap();
- }
- }
- Err(e) => {
- writeln!(stderr.lock(), "FAILED: {}", e).unwrap();
- panic!("failed to execute miri");
- },
- }
- }
- 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);
-
- panic!("ran miri on rustc test suite. Test failing for convenience");
- }
-}
-
#[test]
fn run_pass_miri() {
- if let Ok(_) = std::env::var("MIRI_RUSTC_TEST") {
- return;
- }
-
let sysroot = get_sysroot();
let host = get_host();
#[test]
fn run_pass_rustc() {
- if let Ok(_) = std::env::var("MIRI_RUSTC_TEST") {
- return;
- }
-
run_pass("tests/run-pass");
run_pass("tests/run-pass-fullmir");
}
#[test]
fn compile_fail_miri() {
- if let Ok(_) = std::env::var("MIRI_RUSTC_TEST") {
- return;
- }
-
let sysroot = get_sysroot();
let host = get_host();
});
compile_fail(&sysroot, "tests/compile-fail-fullmir", &host, &host, true);
}
-
-fn print_vec<W: std::io::Write>(stderr: &mut W, v: Vec<String>) {
- 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<T: PartialEq + Ord>(mut v: Vec<T>) -> 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
-}