]> git.lizzy.rs Git - rust.git/commitdiff
Merge branch 'master' into eq-hash
authorRalf Jung <post@ralfj.de>
Fri, 13 Jul 2018 06:29:42 +0000 (08:29 +0200)
committerGitHub <noreply@github.com>
Fri, 13 Jul 2018 06:29:42 +0000 (08:29 +0200)
52 files changed:
Cargo.toml
README.md
src/bin/miri.rs
src/fn_call.rs
src/helpers.rs
src/lib.rs
src/locks.rs
src/operator.rs
src/range_map.rs
src/tls.rs
src/validation.rs
tests/compile-fail-fullmir/deallocate-bad-alignment.rs [new file with mode: 0644]
tests/compile-fail-fullmir/deallocate-bad-size.rs [new file with mode: 0644]
tests/compile-fail-fullmir/deallocate-twice.rs [new file with mode: 0644]
tests/compile-fail-fullmir/out_of_bounds_ptr_1.rs [new file with mode: 0644]
tests/compile-fail-fullmir/out_of_bounds_ptr_2.rs [new file with mode: 0644]
tests/compile-fail-fullmir/ptr_offset_overflow.rs [new file with mode: 0644]
tests/compile-fail-fullmir/reallocate-bad-size.rs [new file with mode: 0644]
tests/compile-fail-fullmir/reallocate-change-alloc.rs [new file with mode: 0644]
tests/compile-fail-fullmir/reallocate-dangling.rs [new file with mode: 0644]
tests/compile-fail-fullmir/stack_free.rs [new file with mode: 0644]
tests/compile-fail-fullmir/undefined_byte_read.rs [deleted file]
tests/compile-fail/deallocate-bad-alignment.rs [deleted file]
tests/compile-fail/deallocate-bad-size.rs [deleted file]
tests/compile-fail/deallocate-twice.rs [deleted file]
tests/compile-fail/match_char.rs
tests/compile-fail/memleak.rs
tests/compile-fail/memleak_rc.rs
tests/compile-fail/out_of_bounds_ptr_1.rs [deleted file]
tests/compile-fail/out_of_bounds_ptr_2.rs [deleted file]
tests/compile-fail/overflowing-rsh-2.rs
tests/compile-fail/panic.rs
tests/compile-fail/ptr_offset_overflow.rs [deleted file]
tests/compile-fail/reallocate-bad-size.rs [deleted file]
tests/compile-fail/reallocate-change-alloc.rs [deleted file]
tests/compile-fail/reallocate-dangling.rs [deleted file]
tests/compile-fail/stack_free.rs [deleted file]
tests/compile-fail/static_memory_modification.rs
tests/compile-fail/undefined_byte_read.rs [new file with mode: 0644]
tests/compiletest.rs
tests/run-pass-fullmir/heap.rs [deleted file]
tests/run-pass-fullmir/issue-15080.rs [deleted file]
tests/run-pass-fullmir/move-arg-2-unique.rs [deleted file]
tests/run-pass-fullmir/regions-mock-trans.rs [deleted file]
tests/run-pass-fullmir/vecs.rs [deleted file]
tests/run-pass/aux_test.rs [deleted file]
tests/run-pass/auxiliary/dep.rs [deleted file]
tests/run-pass/heap.rs [new file with mode: 0644]
tests/run-pass/issue-15080.rs [new file with mode: 0644]
tests/run-pass/move-arg-2-unique.rs [new file with mode: 0644]
tests/run-pass/regions-mock-trans.rs [new file with mode: 0644]
tests/run-pass/vecs.rs [new file with mode: 0644]

index 86ac2c040fd1c73e1377da2b0bbd4f3ae93a0d40..c46ba7c41429500fde27ea6772d9aeb1126c0deb 100644 (file)
@@ -20,8 +20,8 @@ required-features = ["cargo_miri"]
 
 [dependencies]
 byteorder = { version = "1.1", features = ["i128"]}
-cargo_metadata = { version = "0.5", optional = true }
-regex = "0.2.2"
+cargo_metadata = { version = "0.6", optional = true }
+regex = "1.0"
 lazy_static = "1.0"
 env_logger = "0.5.0-rc.1"
 log = "0.4"
@@ -31,3 +31,4 @@ cargo_miri = ["cargo_metadata"]
 
 [dev-dependencies]
 compiletest_rs = { version = "0.3.4", features = ["tmp"] }
+colored = "1.6"
index 7660735a7cefa01289cfb30754b9149b561ea152..d0ae5ec46ff9d9eb498bec9701177fc193a39174 100644 (file)
--- a/README.md
+++ b/README.md
@@ -42,10 +42,22 @@ cargo run --bin miri tests/run-pass-fullmir/vecs.rs # Or whatever test you like.
 
 ## Debugging
 
-You can get detailed, statement-by-statement traces by setting the `MIRI_LOG`
-environment variable to `trace`. These traces are indented based on call stack
-depth. You can get a much less verbose set of information with other logging
-levels such as `warn`.
+Since the heart of miri (the main interpreter engine) lives in rustc, tracing
+the interpreter requires a version of rustc compiled with tracing.  To this
+end, you will have to compile your own rustc:
+```
+git clone https://github.com/rust-lang/rust/ rustc
+cd rustc
+cp config.toml.example config.toml
+# Now edit `config.toml` and set `debug-assertions = true`
+./x.py build
+rustup toolchain link custom build/x86_64-unknown-linux-gnu/stage2
+```
+The `build` step can take 30 to 60 minutes.
+
+Now, in the miri directory, you can `rustup override set custom` and re-build
+everything.  Finally, if you now set `RUST_LOG=rustc_mir::interpret=trace` as
+environment variable, you will get detailed step-by-step tracing information.
 
 ## Running miri on your own project('s test suite)
 
@@ -70,12 +82,15 @@ RUSTFLAGS='-Zalways-encode-mir' xargo build
 Now you can run miri against the libstd compiled by xargo:
 
 ```sh
-MIRI_SYSROOT=~/.xargo/HOST cargo run --bin miri tests/run-pass-fullmir/vecs.rs
+MIRI_SYSROOT=~/.xargo/HOST cargo run --bin miri tests/run-pass-fullmir/hashmap.rs
 ```
 
 Notice that you will have to re-run the last step of the preparations above when
 your toolchain changes (e.g., when you update the nightly).
 
+You can also set `-Zmiri-start-fn` to make miri start evaluation with the
+`start_fn` lang item, instead of starting at the `main` function.
+
 ## Contributing and getting help
 
 Check out the issues on this GitHub repository for some ideas. There's lots that
index 3001500d2e07bf1fb5d0e753e85b6fe24dd43f0a..51c53b4af275d03663deb1c22dc06dc6cac9fe74 100644 (file)
@@ -87,10 +87,7 @@ fn build_controller(
         control.after_hir_lowering.callback = Box::new(after_hir_lowering);
         let start_fn = this.start_fn;
         control.after_analysis.callback = Box::new(move |state| after_analysis(state, start_fn));
-        if sess.target.target != sess.host {
-            // only fully compile targets on the host. linking will fail for cross-compilation.
-            control.after_analysis.stop = Compilation::Stop;
-        }
+        control.after_analysis.stop = Compilation::Stop;
         control
     }
 }
@@ -138,13 +135,12 @@ fn visit_impl_item(&mut self, _impl_item: &'hir hir::ImplItem) {}
         );
     } 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 use_start_fn {
-                Some(start_fn)
-            } else {
-                None
-            }
-        });
+        // Use start_fn lang item if we have -Zmiri-start-fn set
+        let start_wrapper = if use_start_fn {
+            Some(tcx.lang_items().start_fn().unwrap())
+        } else {
+            None
+        };
         miri::eval_main(tcx, entry_def_id, start_wrapper);
 
         state.session.abort_if_errors();
@@ -232,9 +228,6 @@ fn main() {
         }
     });
 
-    // Make sure we always have all the MIR (e.g. for auxilary builds in unit tests).
-    args.push("-Zalways-encode-mir".to_owned());
-
     rustc_driver::run_compiler(&args, Box::new(MiriCompilerCalls {
         default: Box::new(RustcDefaultCalls),
         start_fn,
index 36cc29a2b5b5b7690c3dc92e3e8f98416dffc300..d2149ee5dbe7d3ee75280440acf226f16237b25f 100644 (file)
@@ -199,7 +199,7 @@ fn call_c_abi(
                     self.write_null(dest, dest_ty)?;
                 } else {
                     let align = self.tcx.data_layout.pointer_align;
-                    let ptr = self.memory.allocate(Size::from_bytes(size), align, Some(MemoryKind::C.into()))?;
+                    let ptr = self.memory.allocate(Size::from_bytes(size), align, MemoryKind::C.into())?;
                     self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
                 }
             }
@@ -268,7 +268,7 @@ fn call_c_abi(
                 )?;
                 let mut args = self.frame().mir.args_iter();
 
-                let arg_local = args.next().ok_or(
+                let arg_local = args.next().ok_or_else(||
                     EvalErrorKind::AbiViolation(
                         "Argument to __rust_maybe_catch_panic does not take enough arguments."
                             .to_owned(),
@@ -395,7 +395,7 @@ fn call_c_abi(
                     let value_copy = self.memory.allocate(
                         Size::from_bytes((value.len() + 1) as u64),
                         Align::from_bytes(1, 1).unwrap(),
-                        Some(MemoryKind::Env.into()),
+                        MemoryKind::Env.into(),
                     )?;
                     self.memory.write_bytes(value_copy.into(), &value)?;
                     let trailing_zero_ptr = value_copy.offset(Size::from_bytes(value.len() as u64), &self)?.into();
@@ -504,7 +504,7 @@ fn call_c_abi(
 
                 // Figure out how large a pthread TLS key actually is. This is libc::pthread_key_t.
                 let key_type = args[0].ty.builtin_deref(true)
-                                   .ok_or(EvalErrorKind::AbiViolation("Wrong signature used for pthread_key_create: First argument must be a raw pointer.".to_owned()))?.ty;
+                                   .ok_or_else(|| EvalErrorKind::AbiViolation("Wrong signature used for pthread_key_create: First argument must be a raw pointer.".to_owned()))?.ty;
                 let key_size = self.layout_of(key_type)?.size;
 
                 // Create key and write it into the memory where key_ptr wants it
@@ -656,7 +656,7 @@ fn call_missing_fn(
                 }
                 let ptr = self.memory.allocate(Size::from_bytes(size),
                                                Align::from_bytes(align, align).unwrap(),
-                                               Some(MemoryKind::Rust.into()))?;
+                                               MemoryKind::Rust.into())?;
                 self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
             }
             "alloc::alloc::::__rust_alloc_zeroed" => {
@@ -670,7 +670,7 @@ fn call_missing_fn(
                 }
                 let ptr = self.memory.allocate(Size::from_bytes(size),
                                                Align::from_bytes(align, align).unwrap(),
-                                               Some(MemoryKind::Rust.into()))?;
+                                               MemoryKind::Rust.into())?;
                 self.memory.write_repeat(ptr.into(), 0, Size::from_bytes(size))?;
                 self.write_scalar(dest, Scalar::Ptr(ptr), dest_ty)?;
             }
@@ -747,7 +747,7 @@ fn call_missing_fn(
         // current frame.
         self.dump_local(dest);
         self.goto_block(dest_block);
-        return Ok(());
+        Ok(())
     }
 
     fn write_null(&mut self, dest: Place, dest_ty: Ty<'tcx>) -> EvalResult<'tcx> {
index d881d5c271104564894aacf55721a1df36e53eb4..aa699b509fad8a4210c7ac177b475afdcfe2082f 100644 (file)
@@ -75,7 +75,7 @@ fn pointer_offset(
         }
         // FIXME: assuming here that type size is < i64::max_value()
         let pointee_size = self.layout_of(pointee_ty)?.size.bytes() as i64;
-        return if let Some(offset) = offset.checked_mul(pointee_size) {
+         if let Some(offset) = offset.checked_mul(pointee_size) {
             let ptr = ptr.ptr_signed_offset(offset, self)?;
             // Do not do bounds-checking for integers; they can never alias a normal pointer anyway.
             if let Scalar::Ptr(ptr) = ptr {
@@ -87,7 +87,7 @@ fn pointer_offset(
             Ok(ptr)
         } else {
             err!(Overflow(mir::BinOp::Mul))
-        };
+        }
     }
 
     fn value_to_isize(
index ffb17527ad04f7235d75d85286229d7b8d6bc0b8..75397262b225a1d0d30b1d0b75e8c6f8d83fbae9 100644 (file)
@@ -5,6 +5,8 @@
     inclusive_range_methods,
 )]
 
+#![cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
+
 #[macro_use]
 extern crate log;
 
@@ -24,7 +26,6 @@
 use rustc::ty::subst::Subst;
 use rustc::hir::def_id::DefId;
 use rustc::mir;
-use rustc::middle::const_val;
 
 use rustc_data_structures::fx::FxHasher;
 
@@ -175,7 +176,7 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
         // Return value
         let size = ecx.tcx.data_layout.pointer_size;
         let align = ecx.tcx.data_layout.pointer_align;
-        let ret_ptr = ecx.memory_mut().allocate(size, align, Some(MemoryKind::Stack))?;
+        let ret_ptr = ecx.memory_mut().allocate(size, align, MemoryKind::Stack)?;
         cleanup_ptr = Some(ret_ptr);
 
         // Push our stack frame
@@ -214,7 +215,7 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
         let foo = ecx.memory.allocate_bytes(b"foo\0");
         let ptr_size = ecx.memory.pointer_size();
         let ptr_align = ecx.tcx.data_layout.pointer_align;
-        let foo_ptr = ecx.memory.allocate(ptr_size, ptr_align, None)?;
+        let foo_ptr = ecx.memory.allocate(ptr_size, ptr_align, MemoryKind::Stack)?;
         ecx.memory.write_scalar(foo_ptr.into(), ptr_align, Scalar::Ptr(foo), ptr_size, false)?;
         ecx.memory.mark_static_initialized(foo_ptr.alloc_id, Mutability::Immutable)?;
         ecx.write_ptr(dest, foo_ptr.into(), ty)?;
@@ -273,10 +274,10 @@ pub fn eval_main<'a, 'tcx: 'a>(
                     block.terminator().source_info.span
                 };
 
-                let mut err = const_val::struct_error(ecx.tcx.tcx.at(span), "constant evaluation error");
+                let mut err = struct_error(ecx.tcx.tcx.at(span), "constant evaluation error");
                 let (frames, span) = ecx.generate_stacktrace(None);
                 err.span_label(span, e.to_string());
-                for const_val::FrameInfo { span, location, .. } in frames {
+                for FrameInfo { span, location, .. } in frames {
                     err.span_note(span, &format!("inside call to `{}`", location));
                 }
                 err.emit();
@@ -440,7 +441,7 @@ fn init_static<'a>(
         let ptr = ecx.memory.allocate(
             layout.size,
             layout.align,
-            None,
+            MemoryKind::Stack,
         )?;
 
         // Step 4: Cache allocation id for recursive statics
@@ -463,14 +464,11 @@ fn init_static<'a>(
                 let frame = ecx.frame_mut();
                 let bb = &frame.mir.basic_blocks()[frame.block];
                 if bb.statements.len() == frame.stmt && !bb.is_cleanup {
-                    match bb.terminator().kind {
-                        ::rustc::mir::TerminatorKind::Return => {
-                            for (local, _local_decl) in mir.local_decls.iter_enumerated().skip(1) {
-                                // Don't deallocate locals, because the return value might reference them
-                                frame.storage_dead(local);
-                            }
+                    if let ::rustc::mir::TerminatorKind::Return = bb.terminator().kind {
+                        for (local, _local_decl) in mir.local_decls.iter_enumerated().skip(1) {
+                            // Don't deallocate locals, because the return value might reference them
+                            frame.storage_dead(local);
                         }
-                        _ => {}
                     }
                 }
             }
@@ -514,7 +512,7 @@ fn box_alloc<'a>(
                 value: Value::Scalar(Scalar::from_u128(match layout.size.bytes() {
                     0 => 1 as u128,
                     size => size as u128,
-                }.into())),
+                })),
                 ty: usize,
             },
             dest,
index 9947609d37550a23ccb32abc983ae51899810ee1..9f4126ad82b60002e105863b78712e8f10ae5278 100644 (file)
@@ -241,11 +241,9 @@ fn suspend_write_lock(
                     // All is well
                     continue 'locks;
                 }
-            } else {
-                if !is_our_lock {
-                    // All is well.
-                    continue 'locks;
-                }
+            } else if !is_our_lock {
+                // All is well.
+                continue 'locks;
             }
             // If we get here, releasing this is an error except for NoLock.
             if lock.active != NoLock {
@@ -377,7 +375,7 @@ fn locks_lifetime_ended(&mut self, ending_region: Option<region::Scope>) {
             }
             // Clean up the map
             alloc_locks.retain(|lock| match lock.active {
-                NoLock => lock.suspended.len() > 0,
+                NoLock => !lock.suspended.is_empty(),
                 _ => true,
             });
         }
index f36e749dc9279a010a24d8717c1cd25205619086..1440f1dab4e0fc8187cadb09490907e0d329d7b0 100644 (file)
@@ -69,7 +69,7 @@ fn ptr_op(
                     .expect("Offset called on non-ptr type")
                     .ty;
                 let ptr = self.pointer_offset(
-                    left.into(),
+                    left,
                     pointee_ty,
                     right.to_bits(self.memory.pointer_size())? as i64,
                 )?;
index 118be32a2993b861cc5ba9f14a8cd41b02ef1c0e..76d01ad19e3ab609e5bfafc80aed5ea3c7cf24c7 100644 (file)
@@ -19,7 +19,7 @@ pub struct RangeMap<T> {
 // At the same time the `end` is irrelevant for the sorting and range searching, but used for the check.
 // This kind of search breaks, if `end < start`, so don't do that!
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
-struct Range {
+pub struct Range {
     start: u64,
     end: u64, // Invariant: end > start
 }
@@ -189,7 +189,7 @@ pub fn retain<F>(&mut self, mut f: F)
         F: FnMut(&T) -> bool,
     {
         let mut remove = Vec::new();
-        for (range, data) in self.map.iter() {
+        for (range, data) in &self.map {
             if !f(data) {
                 remove.push(*range);
             }
index 7f49509ef42ea1135a631fce5b45beabb843065d..45805f3aa8cc1199e15b24ede7dfecf42b95f57e 100644 (file)
@@ -30,38 +30,38 @@ fn create_tls_key(&mut self, dtor: Option<ty::Instance<'tcx>>) -> TlsKey {
             },
         );
         trace!("New TLS key allocated: {} with dtor {:?}", new_key, dtor);
-        return new_key;
+        new_key
     }
 
     fn delete_tls_key(&mut self, key: TlsKey) -> EvalResult<'tcx> {
-        return match self.data.thread_local.remove(&key) {
+        match self.data.thread_local.remove(&key) {
             Some(_) => {
                 trace!("TLS key {} removed", key);
                 Ok(())
             }
             None => err!(TlsOutOfBounds),
-        };
+        }
     }
 
     fn load_tls(&mut self, key: TlsKey) -> EvalResult<'tcx, Scalar> {
-        return match self.data.thread_local.get(&key) {
+        match self.data.thread_local.get(&key) {
             Some(&TlsEntry { data, .. }) => {
                 trace!("TLS key {} loaded: {:?}", key, data);
                 Ok(data)
             }
             None => err!(TlsOutOfBounds),
-        };
+        }
     }
 
     fn store_tls(&mut self, key: TlsKey, new_data: Scalar) -> EvalResult<'tcx> {
-        return match self.data.thread_local.get_mut(&key) {
+        match self.data.thread_local.get_mut(&key) {
             Some(&mut TlsEntry { ref mut data, .. }) => {
                 trace!("TLS key {} stored: {:?}", key, new_data);
                 *data = new_data;
                 Ok(())
             }
             None => err!(TlsOutOfBounds),
-        };
+        }
     }
 
     /// Returns a dtor, its argument and its index, if one is supposed to run
@@ -104,7 +104,7 @@ fn fetch_tls_dtor(
                 }
             }
         }
-        return Ok(None);
+        Ok(None)
     }
 }
 
@@ -124,8 +124,8 @@ fn run_tls_dtors(&mut self) -> EvalResult<'tcx> {
                 Place::undef(),
                 StackPopCleanup::None,
             )?;
-            let arg_local = self.frame().mir.args_iter().next().ok_or(
-                EvalErrorKind::AbiViolation("TLS dtor does not take enough arguments.".to_owned()),
+            let arg_local = self.frame().mir.args_iter().next().ok_or_else(
+                || EvalErrorKind::AbiViolation("TLS dtor does not take enough arguments.".to_owned()),
             )?;
             let dest = self.eval_place(&mir::Place::Local(arg_local))?;
             let ty = self.tcx.mk_mut_ptr(self.tcx.types.u8);
index d82a345c2512aacefd8ddc866fa2b9b4f9633de3..758fd5d274701c409415b8e42f1504a0978eaf8d 100644 (file)
@@ -8,7 +8,7 @@
 use rustc::traits::{self, TraitEngine};
 use rustc::infer::InferCtxt;
 use rustc::middle::region;
-use rustc::middle::const_val::ConstVal;
+use rustc::mir::interpret::{ConstValue};
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_mir::interpret::HasMemory;
 
@@ -135,10 +135,10 @@ fn abstract_place_projection(&self, proj: &mir::PlaceProjection<'tcx>) -> EvalRe
     }
 
     fn abstract_place(&self, place: &mir::Place<'tcx>) -> EvalResult<'tcx, AbsPlace<'tcx>> {
-        Ok(match place {
-            &mir::Place::Local(l) => AbsPlace::Local(l),
-            &mir::Place::Static(ref s) => AbsPlace::Static(s.def_id),
-            &mir::Place::Projection(ref p) =>
+        Ok(match *place {
+            mir::Place::Local(l) => AbsPlace::Local(l),
+            mir::Place::Static(ref s) => AbsPlace::Static(s.def_id),
+            mir::Place::Projection(ref p) =>
                 AbsPlace::Projection(Box::new(self.abstract_place_projection(&*p)?)),
         })
     }
@@ -378,11 +378,8 @@ fn field_with_lifetimes(
         mut layout: ty::layout::TyLayout<'tcx>,
         i: usize,
     ) -> EvalResult<'tcx, Ty<'tcx>> {
-        match base {
-            Place::Ptr { extra: PlaceExtra::DowncastVariant(variant_index), .. } => {
-                layout = layout.for_variant(&self, variant_index);
-            }
-            _ => {}
+        if let Place::Ptr { extra: PlaceExtra::DowncastVariant(variant_index), .. } = base {
+            layout = layout.for_variant(&self, variant_index);
         }
         let tcx = self.tcx.tcx;
         Ok(match layout.ty.sty {
@@ -667,12 +664,11 @@ fn validate(
                     // Inner lifetimes *outlive* outer ones, so only if we have no lifetime restriction yet,
                     // we record the region of this borrow to the context.
                     if query.re == None {
-                        match *region {
-                            ReScope(scope) => query.re = Some(scope),
-                            // It is possible for us to encounter erased lifetimes here because the lifetimes in
-                            // this functions' Subst will be erased.
-                            _ => {}
+                        if let ReScope(scope) = *region {
+                            query.re = Some(scope);
                         }
+                        // It is possible for us to encounter erased lifetimes here because the lifetimes in
+                        // this functions' Subst will be erased.
                     }
                     self.validate_ptr(val, query.place.0, pointee_ty, query.re, query.mutbl, mode)?;
                 }
@@ -719,14 +715,14 @@ fn validate(
                 }
                 TyArray(elem_ty, len) => {
                     let len = match len.val {
-                        ConstVal::Unevaluated(def_id, substs) => {
+                        ConstValue::Unevaluated(def_id, substs) => {
                             self.tcx.const_eval(self.tcx.param_env(def_id).and(GlobalId {
                                 instance: Instance::new(def_id, substs),
                                 promoted: None,
                             }))
                                 .map_err(|_err|EvalErrorKind::MachineError("<already reported>".to_string()))?
                         }
-                        ConstVal::Value(_) => len,
+                        _ => len,
                     };
                     let len = len.unwrap_usize(self.tcx.tcx);
                     for i in 0..len {
@@ -772,7 +768,7 @@ fn validate(
                             let variant_idx = self.read_discriminant_as_variant_index(query.place.1, query.ty)?;
                             let variant = &adt.variants[variant_idx];
 
-                            if variant.fields.len() > 0 {
+                            if !variant.fields.is_empty() {
                                 // Downcast to this variant, if needed
                                 let place = if adt.is_enum() {
                                     (
diff --git a/tests/compile-fail-fullmir/deallocate-bad-alignment.rs b/tests/compile-fail-fullmir/deallocate-bad-alignment.rs
new file mode 100644 (file)
index 0000000..4b89f0a
--- /dev/null
@@ -0,0 +1,15 @@
+#![feature(alloc, allocator_api)]
+
+extern crate alloc;
+
+use alloc::alloc::Global;
+use std::alloc::*;
+
+// error-pattern: incorrect alloc info: expected size 1 and align 2, got size 1 and align 1
+
+fn main() {
+    unsafe {
+        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
+        Global.dealloc(x, Layout::from_size_align_unchecked(1, 2));
+    }
+}
diff --git a/tests/compile-fail-fullmir/deallocate-bad-size.rs b/tests/compile-fail-fullmir/deallocate-bad-size.rs
new file mode 100644 (file)
index 0000000..3a74245
--- /dev/null
@@ -0,0 +1,15 @@
+#![feature(alloc, allocator_api)]
+
+extern crate alloc;
+
+use alloc::alloc::Global;
+use std::alloc::*;
+
+// error-pattern: incorrect alloc info: expected size 2 and align 1, got size 1 and align 1
+
+fn main() {
+    unsafe {
+        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
+        Global.dealloc(x, Layout::from_size_align_unchecked(2, 1));
+    }
+}
diff --git a/tests/compile-fail-fullmir/deallocate-twice.rs b/tests/compile-fail-fullmir/deallocate-twice.rs
new file mode 100644 (file)
index 0000000..613edf3
--- /dev/null
@@ -0,0 +1,16 @@
+#![feature(alloc, allocator_api)]
+
+extern crate alloc;
+
+use alloc::alloc::Global;
+use std::alloc::*;
+
+// error-pattern: tried to deallocate dangling pointer
+
+fn main() {
+    unsafe {
+        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
+        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
+        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
+    }
+}
diff --git a/tests/compile-fail-fullmir/out_of_bounds_ptr_1.rs b/tests/compile-fail-fullmir/out_of_bounds_ptr_1.rs
new file mode 100644 (file)
index 0000000..8dce7e5
--- /dev/null
@@ -0,0 +1,8 @@
+// error-pattern: pointer computed at offset 5, outside bounds of allocation
+fn main() {
+    let v = [0i8; 4];
+    let x = &v as *const i8;
+    // The error is inside another function, so we cannot match it by line
+    let x = unsafe { x.offset(5) };
+    panic!("this should never print: {:?}", x);
+}
diff --git a/tests/compile-fail-fullmir/out_of_bounds_ptr_2.rs b/tests/compile-fail-fullmir/out_of_bounds_ptr_2.rs
new file mode 100644 (file)
index 0000000..e19a616
--- /dev/null
@@ -0,0 +1,7 @@
+// error-pattern: attempt to add with overflow
+fn main() {
+    let v = [0i8; 4];
+    let x = &v as *const i8;
+    let x = unsafe { x.offset(-1) };
+    panic!("this should never print: {:?}", x);
+}
diff --git a/tests/compile-fail-fullmir/ptr_offset_overflow.rs b/tests/compile-fail-fullmir/ptr_offset_overflow.rs
new file mode 100644 (file)
index 0000000..32ab2da
--- /dev/null
@@ -0,0 +1,6 @@
+//error-pattern: attempt to add with overflow
+fn main() {
+    let v = [1i8, 2];
+    let x = &v[1] as *const i8;
+    let _ = unsafe { x.offset(isize::min_value()) };
+}
diff --git a/tests/compile-fail-fullmir/reallocate-bad-size.rs b/tests/compile-fail-fullmir/reallocate-bad-size.rs
new file mode 100644 (file)
index 0000000..f85b651
--- /dev/null
@@ -0,0 +1,15 @@
+#![feature(alloc, allocator_api)]
+
+extern crate alloc;
+
+use alloc::alloc::Global;
+use std::alloc::*;
+
+// error-pattern: incorrect alloc info: expected size 2 and align 1, got size 1 and align 1
+
+fn main() {
+    unsafe {
+        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
+        let _y = Global.realloc(x, Layout::from_size_align_unchecked(2, 1), 1).unwrap();
+    }
+}
diff --git a/tests/compile-fail-fullmir/reallocate-change-alloc.rs b/tests/compile-fail-fullmir/reallocate-change-alloc.rs
new file mode 100644 (file)
index 0000000..03040cd
--- /dev/null
@@ -0,0 +1,15 @@
+#![feature(alloc, allocator_api)]
+
+extern crate alloc;
+
+use alloc::alloc::Global;
+use std::alloc::*;
+
+fn main() {
+    unsafe {
+        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
+        let _y = Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1).unwrap();
+        let _z = *(x.as_ptr() as *mut u8); //~ ERROR constant evaluation error [E0080]
+        //~^ NOTE dangling pointer was dereferenced
+    }
+}
diff --git a/tests/compile-fail-fullmir/reallocate-dangling.rs b/tests/compile-fail-fullmir/reallocate-dangling.rs
new file mode 100644 (file)
index 0000000..6dfb7fe
--- /dev/null
@@ -0,0 +1,16 @@
+#![feature(alloc, allocator_api)]
+
+extern crate alloc;
+
+use alloc::alloc::Global;
+use std::alloc::*;
+
+// error-pattern: dangling pointer was dereferenced
+
+fn main() {
+    unsafe {
+        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1)).unwrap();
+        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
+        Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1).unwrap();
+    }
+}
diff --git a/tests/compile-fail-fullmir/stack_free.rs b/tests/compile-fail-fullmir/stack_free.rs
new file mode 100644 (file)
index 0000000..96006c8
--- /dev/null
@@ -0,0 +1,7 @@
+// error-pattern: tried to deallocate Stack memory but gave Machine(Rust) as the kind
+
+fn main() {
+    let x = 42;
+    let bad_box = unsafe { std::mem::transmute::<&i32, Box<i32>>(&x) };
+    drop(bad_box);
+}
diff --git a/tests/compile-fail-fullmir/undefined_byte_read.rs b/tests/compile-fail-fullmir/undefined_byte_read.rs
deleted file mode 100644 (file)
index 99404b7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// This should fail even without validation
-// compile-flags: -Zmir-emit-validate=0
-
-fn main() {
-    let v: Vec<u8> = Vec::with_capacity(10);
-    let undef = unsafe { *v.get_unchecked(5) };
-    let x = undef + 1; //~ ERROR: attempted to read undefined bytes
-    panic!("this should never print: {}", x);
-}
diff --git a/tests/compile-fail/deallocate-bad-alignment.rs b/tests/compile-fail/deallocate-bad-alignment.rs
deleted file mode 100644 (file)
index 36e99cb..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(alloc, allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::*;
-
-// error-pattern: incorrect alloc info: expected size 1 and align 2, got size 1 and align 1
-
-fn main() {
-    unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1));
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 2));
-    }
-}
diff --git a/tests/compile-fail/deallocate-bad-size.rs b/tests/compile-fail/deallocate-bad-size.rs
deleted file mode 100644 (file)
index f1271ce..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(alloc, allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::*;
-
-// error-pattern: incorrect alloc info: expected size 2 and align 1, got size 1 and align 1
-
-fn main() {
-    unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1));
-        Global.dealloc(x, Layout::from_size_align_unchecked(2, 1));
-    }
-}
diff --git a/tests/compile-fail/deallocate-twice.rs b/tests/compile-fail/deallocate-twice.rs
deleted file mode 100644 (file)
index 58fcb74..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#![feature(alloc, allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::*;
-
-// error-pattern: tried to deallocate dangling pointer
-
-fn main() {
-    unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1));
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
-    }
-}
index 15ce2f2f79525912bca237d72d1d8325ba4c51ef..0d45d70eb781ac7564c209fd3564a61642deca33 100644 (file)
@@ -1,3 +1,5 @@
+// ignore-test FIXME: we are not checking these things on match any more?
+
 fn main() {
     assert!(std::char::from_u32(-1_i32 as u32).is_none());
     match unsafe { std::mem::transmute::<i32, char>(-1) } { //~ ERROR constant evaluation error [E0080]
index 71b4e2f442f31db02b4d710d3ede9917c51f9dcc..c03cf50eb27f613f6100a24ef02163c61a8cfe70 100644 (file)
@@ -1,3 +1,4 @@
+// ignore-test FIXME: leak detection is disabled
 //error-pattern: the evaluated program leaked memory
 
 fn main() {
index b2bc6722afb04fd22c6a0bc4b546ecab3fe1e5ac..da3a58118a2a5671f295b67f0af108889988c70a 100644 (file)
@@ -1,3 +1,4 @@
+// ignore-test FIXME: leak detection is disabled
 //error-pattern: the evaluated program leaked memory
 
 use std::rc::Rc;
diff --git a/tests/compile-fail/out_of_bounds_ptr_1.rs b/tests/compile-fail/out_of_bounds_ptr_1.rs
deleted file mode 100644 (file)
index 8dce7e5..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-// error-pattern: pointer computed at offset 5, outside bounds of allocation
-fn main() {
-    let v = [0i8; 4];
-    let x = &v as *const i8;
-    // The error is inside another function, so we cannot match it by line
-    let x = unsafe { x.offset(5) };
-    panic!("this should never print: {:?}", x);
-}
diff --git a/tests/compile-fail/out_of_bounds_ptr_2.rs b/tests/compile-fail/out_of_bounds_ptr_2.rs
deleted file mode 100644 (file)
index e19a616..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// error-pattern: attempt to add with overflow
-fn main() {
-    let v = [0i8; 4];
-    let x = &v as *const i8;
-    let x = unsafe { x.offset(-1) };
-    panic!("this should never print: {:?}", x);
-}
index 4447b9d7579a7b9e2d91de423bbd909c64bef5f8..967c8b020cca099781347a769c233d13f45d4585 100644 (file)
@@ -13,5 +13,5 @@
 fn main() {
     // Make sure we catch overflows that would be hidden by first casting the RHS to u32
     let _n = 1i64 >> (u32::max_value() as i64 + 1); //~ ERROR constant evaluation error [E0080]
-    //~^ NOTE suiriuruihrihue
+    //~^ NOTE attempt to shift right with overflow
 }
index 80149eeffaa641c32a70dc2dc04645c2a426658e..1f9e8f6e1d0b0b3af0eee73d145713785e6c8fd0 100644 (file)
@@ -1,3 +1,4 @@
+//ignore-windows
 // FIXME: Something in panic handling fails validation with full-MIR
 // compile-flags: -Zmir-emit-validate=0
 //error-pattern: the evaluated program panicked
diff --git a/tests/compile-fail/ptr_offset_overflow.rs b/tests/compile-fail/ptr_offset_overflow.rs
deleted file mode 100644 (file)
index 32ab2da..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-//error-pattern: attempt to add with overflow
-fn main() {
-    let v = [1i8, 2];
-    let x = &v[1] as *const i8;
-    let _ = unsafe { x.offset(isize::min_value()) };
-}
diff --git a/tests/compile-fail/reallocate-bad-size.rs b/tests/compile-fail/reallocate-bad-size.rs
deleted file mode 100644 (file)
index d75c195..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(alloc, allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::*;
-
-// error-pattern: incorrect alloc info: expected size 2 and align 1, got size 1 and align 1
-
-fn main() {
-    unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1));
-        let _y = Global.realloc(x, Layout::from_size_align_unchecked(2, 1), 1);
-    }
-}
diff --git a/tests/compile-fail/reallocate-change-alloc.rs b/tests/compile-fail/reallocate-change-alloc.rs
deleted file mode 100644 (file)
index d8234e9..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(alloc, allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::*;
-
-fn main() {
-    unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1));
-        let _y = Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
-        let _z = *(x as *mut u8); //~ ERROR constant evaluation error [E0080]
-        //~^ NOTE dangling pointer was dereferenced
-    }
-}
diff --git a/tests/compile-fail/reallocate-dangling.rs b/tests/compile-fail/reallocate-dangling.rs
deleted file mode 100644 (file)
index 39b6040..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#![feature(alloc, allocator_api)]
-
-extern crate alloc;
-
-use alloc::alloc::Global;
-use std::alloc::*;
-
-// error-pattern: dangling pointer was dereferenced
-
-fn main() {
-    unsafe {
-        let x = Global.alloc(Layout::from_size_align_unchecked(1, 1));
-        Global.dealloc(x, Layout::from_size_align_unchecked(1, 1));
-        Global.realloc(x, Layout::from_size_align_unchecked(1, 1), 1);
-    }
-}
diff --git a/tests/compile-fail/stack_free.rs b/tests/compile-fail/stack_free.rs
deleted file mode 100644 (file)
index 96006c8..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// error-pattern: tried to deallocate Stack memory but gave Machine(Rust) as the kind
-
-fn main() {
-    let x = 42;
-    let bad_box = unsafe { std::mem::transmute::<&i32, Box<i32>>(&x) };
-    drop(bad_box);
-}
index 7182f40d994dd834ebd3f581d2e1fba49c5ec25c..a85ff545ee4239e36552db4e5df696acf8b579fd 100644 (file)
@@ -1,3 +1,4 @@
+// ignore-test FIXME: we are not making these statics read-only any more?
 static X: usize = 5;
 
 #[allow(mutable_transmutes)]
diff --git a/tests/compile-fail/undefined_byte_read.rs b/tests/compile-fail/undefined_byte_read.rs
new file mode 100644 (file)
index 0000000..24718bc
--- /dev/null
@@ -0,0 +1,10 @@
+// This should fail even without validation
+// compile-flags: -Zmir-emit-validate=0
+
+fn main() {
+    let v: Vec<u8> = Vec::with_capacity(10);
+    let undef = unsafe { *v.get_unchecked(5) };
+    let x = undef + 1; //~ ERROR: error
+    //~^ NOTE attempted to read undefined bytes
+    panic!("this should never print: {}", x);
+}
index e62fa4e65e63045de6ce1b91d34a9868a0d13f27..896d1cae5969e921c448e4df4793508f852acc5c 100644 (file)
@@ -1,6 +1,9 @@
 #![feature(slice_concat_ext)]
 
 extern crate compiletest_rs as compiletest;
+extern crate colored;
+
+use colored::*;
 
 use std::slice::SliceConcatExt;
 use std::path::{PathBuf, Path};
@@ -30,12 +33,26 @@ fn rustc_lib_path() -> PathBuf {
     option_env!("RUSTC_LIB_PATH").unwrap().into()
 }
 
-fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, fullmir: bool) {
-    eprintln!(
+fn have_fullmir() -> bool {
+    // We assume we have full MIR when MIRI_SYSROOT is set or when we are in rustc
+    std::env::var("MIRI_SYSROOT").is_ok() || rustc_test_suite().is_some()
+}
+
+fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir: bool) {
+    if need_fullmir && !have_fullmir() {
+        eprintln!("{}", format!(
+            "## Skipping compile-fail tests in {} against miri for target {} due to missing mir",
+            path,
+            target
+        ).yellow().bold());
+        return;
+    }
+
+    eprintln!("{}", format!(
         "## Running compile-fail tests in {} against miri for target {}",
         path,
         target
-    );
+    ).green().bold());
     let mut config = compiletest::Config::default().tempdir();
     config.mode = "compile-fail".parse().expect("Invalid mode");
     config.rustc_path = miri_path();
@@ -44,29 +61,17 @@ fn compile_fail(sysroot: &Path, path: &str, target: &str, host: &str, fullmir: b
         config.run_lib_path = rustc_lib_path();
         config.compile_lib_path = rustc_lib_path();
     }
-    // if we are building as part of the rustc test suite, we already have fullmir for everything
-    if fullmir && rustc_test_suite().is_none() {
-        if host != target {
-            // skip fullmir on nonhost
-            return;
-        }
-        let sysroot = std::env::home_dir().unwrap()
-            .join(".xargo")
-            .join("HOST");
-        flags.push(format!("--sysroot {}", sysroot.to_str().unwrap()));
-        config.src_base = PathBuf::from(path.to_string());
-    } else {
-        flags.push(format!("--sysroot {}", sysroot.to_str().unwrap()));
-        config.src_base = PathBuf::from(path.to_string());
-    }
+    flags.push(format!("--sysroot {}", sysroot.display()));
+    config.src_base = PathBuf::from(path.to_string());
     flags.push("-Zmir-emit-validate=1".to_owned());
     config.target_rustcflags = Some(flags.join(" "));
     config.target = target.to_owned();
+    config.host = host.to_owned();
     compiletest::run_tests(&config);
 }
 
-fn run_pass(path: &str) {
-    eprintln!("## Running run-pass tests in {} against rustc", path);
+fn rustc_pass(sysroot: &Path, path: &str) {
+    eprintln!("{}", format!("## Running run-pass tests in {} against rustc", path).green().bold());
     let mut config = compiletest::Config::default().tempdir();
     config.mode = "run-pass".parse().expect("Invalid mode");
     config.src_base = PathBuf::from(path);
@@ -74,7 +79,7 @@ fn run_pass(path: &str) {
         config.rustc_path = rustc_path;
         config.run_lib_path = rustc_lib_path();
         config.compile_lib_path = rustc_lib_path();
-        config.target_rustcflags = Some(format!("-Dwarnings --sysroot {}", get_sysroot().display()));
+        config.target_rustcflags = Some(format!("-Dwarnings --sysroot {}", sysroot.display()));
     } else {
         config.target_rustcflags = Some("-Dwarnings".to_owned());
     }
@@ -82,14 +87,23 @@ fn run_pass(path: &str) {
     compiletest::run_tests(&config);
 }
 
-fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool, opt: bool) {
+fn miri_pass(sysroot: &Path, path: &str, target: &str, host: &str, need_fullmir: bool, opt: bool) {
+    if need_fullmir && !have_fullmir() {
+        eprintln!("{}", format!(
+            "## Skipping run-pass tests in {} against miri for target {} due to missing mir",
+            path,
+            target
+        ).yellow().bold());
+        return;
+    }
+
     let opt_str = if opt { " with optimizations" } else { "" };
-    eprintln!(
+    eprintln!("{}", format!(
         "## Running run-pass tests in {} against miri for target {}{}",
         path,
         target,
         opt_str
-    );
+    ).green().bold());
     let mut config = compiletest::Config::default().tempdir();
     config.mode = "ui".parse().expect("Invalid mode");
     config.src_base = PathBuf::from(path);
@@ -101,21 +115,9 @@ fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool, opt: bool) {
         config.compile_lib_path = rustc_lib_path();
     }
     let mut flags = Vec::new();
-    // Control miri logging. This is okay despite concurrent test execution as all tests
-    // will set this env var to the same value.
-    env::set_var("MIRI_LOG", "warn");
-    // if we are building as part of the rustc test suite, we already have fullmir for everything
-    if fullmir && rustc_test_suite().is_none() {
-        if host != target {
-            // skip fullmir on nonhost
-            return;
-        }
-        let sysroot = std::env::home_dir().unwrap()
-            .join(".xargo")
-            .join("HOST");
-
+    flags.push(format!("--sysroot {}", sysroot.display()));
+    if have_fullmir() {
         flags.push("-Zmiri-start-fn".to_owned());
-        flags.push(format!("--sysroot {}", sysroot.to_str().unwrap()));
     }
     if opt {
         flags.push("-Zmir-opt-level=3".to_owned());
@@ -124,6 +126,9 @@ fn miri_pass(path: &str, target: &str, host: &str, fullmir: bool, opt: bool) {
         // For now, only validate without optimizations.  Inlining breaks validation.
         flags.push("-Zmir-emit-validate=1".to_owned());
     }
+    // Control miri logging. This is okay despite concurrent test execution as all tests
+    // will set this env var to the same value.
+    env::set_var("MIRI_LOG", "warn");
     config.target_rustcflags = Some(flags.join(" "));
     compiletest::run_tests(&config);
 }
@@ -180,36 +185,39 @@ fn run_pass_miri(opt: bool) {
     let host = get_host();
 
     for_all_targets(&sysroot, |target| {
-        miri_pass("tests/run-pass", &target, &host, false, opt);
+        miri_pass(&sysroot, "tests/run-pass", &target, &host, false, opt);
     });
-    miri_pass("tests/run-pass-fullmir", &host, &host, true, opt);
-}
-
-#[test]
-fn run_pass_miri_noopt() {
-    run_pass_miri(false);
+    miri_pass(&sysroot, "tests/run-pass-fullmir", &host, &host, true, opt);
 }
 
-#[test]
-#[ignore] // FIXME: Disabled for now, as the optimizer is pretty broken and crashes...
-fn run_pass_miri_opt() {
-    run_pass_miri(true);
-}
-
-#[test]
 fn run_pass_rustc() {
-    run_pass("tests/run-pass");
-    run_pass("tests/run-pass-fullmir");
+    let sysroot = get_sysroot();
+    rustc_pass(&sysroot, "tests/run-pass");
+    rustc_pass(&sysroot, "tests/run-pass-fullmir");
 }
 
-#[test]
-#[should_panic] // TODO: update test errors
 fn compile_fail_miri() {
     let sysroot = get_sysroot();
     let host = get_host();
 
     // FIXME: run tests for other targets, too
-    compile_fail(&sysroot, "tests/compile-fail", &host, &host, true);
-
+    compile_fail(&sysroot, "tests/compile-fail", &host, &host, false);
     compile_fail(&sysroot, "tests/compile-fail-fullmir", &host, &host, true);
 }
+
+#[test]
+fn test() {
+    // We put everything into a single test to avoid the parallelism `cargo test`
+    // introduces.  We still get parallelism within our tests because `compiletest`
+    // uses `libtest` which runs jobs in parallel.
+
+    run_pass_rustc();
+
+    run_pass_miri(false);
+
+    // FIXME: Disabled for now, as the optimizer is pretty broken and crashes...
+    // See https://github.com/rust-lang/rust/issues/50411
+    //run_pass_miri(true);
+
+    compile_fail_miri();
+}
diff --git a/tests/run-pass-fullmir/heap.rs b/tests/run-pass-fullmir/heap.rs
deleted file mode 100644 (file)
index 917d51d..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-//ignore-msvc
-#![feature(box_syntax)]
-
-fn make_box() -> Box<(i16, i16)> {
-    Box::new((1, 2))
-}
-
-fn make_box_syntax() -> Box<(i16, i16)> {
-    box (1, 2)
-}
-
-fn allocate_reallocate() {
-    let mut s = String::new();
-
-    // 6 byte heap alloc (__rust_allocate)
-    s.push_str("foobar");
-    assert_eq!(s.len(), 6);
-    assert_eq!(s.capacity(), 6);
-
-    // heap size doubled to 12 (__rust_reallocate)
-    s.push_str("baz");
-    assert_eq!(s.len(), 9);
-    assert_eq!(s.capacity(), 12);
-
-    // heap size reduced to 9  (__rust_reallocate)
-    s.shrink_to_fit();
-    assert_eq!(s.len(), 9);
-    assert_eq!(s.capacity(), 9);
-}
-
-fn main() {
-    assert_eq!(*make_box(), (1, 2));
-    assert_eq!(*make_box_syntax(), (1, 2));
-    allocate_reallocate();
-}
diff --git a/tests/run-pass-fullmir/issue-15080.rs b/tests/run-pass-fullmir/issue-15080.rs
deleted file mode 100644 (file)
index 4a84f2b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//ignore-msvc
-
-#![feature(slice_patterns)]
-
-fn main() {
-    let mut x: &[_] = &[1, 2, 3, 4];
-
-    let mut result = vec!();
-    loop {
-        x = match *x {
-            [1, n, 3, ref rest..] => {
-                result.push(n);
-                rest
-            }
-            [n, ref rest..] => {
-                result.push(n);
-                rest
-            }
-            [] =>
-                break
-        }
-    }
-    assert_eq!(result, [2, 4]);
-}
diff --git a/tests/run-pass-fullmir/move-arg-2-unique.rs b/tests/run-pass-fullmir/move-arg-2-unique.rs
deleted file mode 100644 (file)
index f3c6566..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//ignore-msvc
-
-#![allow(unused_features, unused_variables)]
-#![feature(box_syntax)]
-
-fn test(foo: Box<Vec<isize>> ) { assert_eq!((*foo)[0], 10); }
-
-pub fn main() {
-    let x = box vec![10];
-    // Test forgetting a local by move-in
-    test(x);
-}
diff --git a/tests/run-pass-fullmir/regions-mock-trans.rs b/tests/run-pass-fullmir/regions-mock-trans.rs
deleted file mode 100644 (file)
index cef62e4..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// FIXME: We handle uninitialzied storage here, which currently makes validation fail.
-// compile-flags: -Zmir-emit-validate=0
-
-//ignore-msvc
-
-#![feature(libc)]
-
-#![allow(dead_code)]
-
-extern crate libc;
-use std::mem;
-
-struct Arena(());
-
-struct Bcx<'a> {
-    fcx: &'a Fcx<'a>
-}
-
-struct Fcx<'a> {
-    arena: &'a Arena,
-    ccx: &'a Ccx
-}
-
-struct Ccx {
-    x: isize
-}
-
-fn alloc<'a>(_bcx : &'a Arena) -> &'a Bcx<'a> {
-    unsafe {
-        mem::transmute(libc::malloc(mem::size_of::<Bcx<'a>>()
-            as libc::size_t))
-    }
-}
-
-fn h<'a>(bcx : &'a Bcx<'a>) -> &'a Bcx<'a> {
-    return alloc(bcx.fcx.arena);
-}
-
-fn g(fcx : &Fcx) {
-    let bcx = Bcx { fcx: fcx };
-    let bcx2 = h(&bcx);
-    unsafe {
-        libc::free(mem::transmute(bcx2));
-    }
-}
-
-fn f(ccx : &Ccx) {
-    let a = Arena(());
-    let fcx = Fcx { arena: &a, ccx: ccx };
-    return g(&fcx);
-}
-
-pub fn main() {
-    let ccx = Ccx { x: 0 };
-    f(&ccx);
-}
diff --git a/tests/run-pass-fullmir/vecs.rs b/tests/run-pass-fullmir/vecs.rs
deleted file mode 100644 (file)
index 9a8912a..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-//ignore-msvc
-
-fn make_vec() -> Vec<u8> {
-    let mut v = Vec::with_capacity(4);
-    v.push(1);
-    v.push(2);
-    v
-}
-
-fn make_vec_macro() -> Vec<u8> {
-    vec![1, 2]
-}
-
-fn make_vec_macro_repeat() -> Vec<u8> {
-    vec![42; 5]
-}
-
-fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
-    vec![0; 7]
-}
-
-fn vec_into_iter() -> u8 {
-    vec![1, 2, 3, 4]
-        .into_iter()
-        .map(|x| x * x)
-        .fold(0, |x, y| x + y)
-}
-
-fn vec_into_iter_zst() -> usize {
-    vec![[0u64; 0], [0u64; 0]]
-        .into_iter()
-        .map(|x| x.len())
-        .sum()
-}
-
-fn vec_reallocate() -> Vec<u8> {
-    let mut v = vec![1, 2];
-    v.push(3);
-    v.push(4);
-    v.push(5);
-    v
-}
-
-fn main() {
-    assert_eq!(vec_reallocate().len(), 5);
-    assert_eq!(vec_into_iter(), 30);
-    assert_eq!(vec_into_iter_zst(), 0);
-    assert_eq!(make_vec().capacity(), 4);
-    assert_eq!(make_vec_macro(), [1, 2]);
-    assert_eq!(make_vec_macro_repeat(), [42; 5]);
-    assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);
-}
diff --git a/tests/run-pass/aux_test.rs b/tests/run-pass/aux_test.rs
deleted file mode 100644 (file)
index beed82e..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-// aux-build:dep.rs
-
-// ignore-cross-compile
-
-extern crate dep;
-
-fn main() {
-    dep::foo();
-}
diff --git a/tests/run-pass/auxiliary/dep.rs b/tests/run-pass/auxiliary/dep.rs
deleted file mode 100644 (file)
index b76b432..0000000
+++ /dev/null
@@ -1 +0,0 @@
-pub fn foo() {}
diff --git a/tests/run-pass/heap.rs b/tests/run-pass/heap.rs
new file mode 100644 (file)
index 0000000..917d51d
--- /dev/null
@@ -0,0 +1,35 @@
+//ignore-msvc
+#![feature(box_syntax)]
+
+fn make_box() -> Box<(i16, i16)> {
+    Box::new((1, 2))
+}
+
+fn make_box_syntax() -> Box<(i16, i16)> {
+    box (1, 2)
+}
+
+fn allocate_reallocate() {
+    let mut s = String::new();
+
+    // 6 byte heap alloc (__rust_allocate)
+    s.push_str("foobar");
+    assert_eq!(s.len(), 6);
+    assert_eq!(s.capacity(), 6);
+
+    // heap size doubled to 12 (__rust_reallocate)
+    s.push_str("baz");
+    assert_eq!(s.len(), 9);
+    assert_eq!(s.capacity(), 12);
+
+    // heap size reduced to 9  (__rust_reallocate)
+    s.shrink_to_fit();
+    assert_eq!(s.len(), 9);
+    assert_eq!(s.capacity(), 9);
+}
+
+fn main() {
+    assert_eq!(*make_box(), (1, 2));
+    assert_eq!(*make_box_syntax(), (1, 2));
+    allocate_reallocate();
+}
diff --git a/tests/run-pass/issue-15080.rs b/tests/run-pass/issue-15080.rs
new file mode 100644 (file)
index 0000000..4a84f2b
--- /dev/null
@@ -0,0 +1,34 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//ignore-msvc
+
+#![feature(slice_patterns)]
+
+fn main() {
+    let mut x: &[_] = &[1, 2, 3, 4];
+
+    let mut result = vec!();
+    loop {
+        x = match *x {
+            [1, n, 3, ref rest..] => {
+                result.push(n);
+                rest
+            }
+            [n, ref rest..] => {
+                result.push(n);
+                rest
+            }
+            [] =>
+                break
+        }
+    }
+    assert_eq!(result, [2, 4]);
+}
diff --git a/tests/run-pass/move-arg-2-unique.rs b/tests/run-pass/move-arg-2-unique.rs
new file mode 100644 (file)
index 0000000..f3c6566
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//ignore-msvc
+
+#![allow(unused_features, unused_variables)]
+#![feature(box_syntax)]
+
+fn test(foo: Box<Vec<isize>> ) { assert_eq!((*foo)[0], 10); }
+
+pub fn main() {
+    let x = box vec![10];
+    // Test forgetting a local by move-in
+    test(x);
+}
diff --git a/tests/run-pass/regions-mock-trans.rs b/tests/run-pass/regions-mock-trans.rs
new file mode 100644 (file)
index 0000000..74e94dd
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// FIXME: We handle uninitialized storage here, which currently makes validation fail.
+// compile-flags: -Zmir-emit-validate=0
+
+//ignore-msvc
+
+#![feature(libc)]
+
+#![allow(dead_code)]
+
+extern crate libc;
+use std::mem;
+
+struct Arena(());
+
+struct Bcx<'a> {
+    fcx: &'a Fcx<'a>
+}
+
+struct Fcx<'a> {
+    arena: &'a Arena,
+    ccx: &'a Ccx
+}
+
+struct Ccx {
+    x: isize
+}
+
+fn alloc<'a>(_bcx : &'a Arena) -> &'a Bcx<'a> {
+    unsafe {
+        mem::transmute(libc::malloc(mem::size_of::<Bcx<'a>>()
+            as libc::size_t))
+    }
+}
+
+fn h<'a>(bcx : &'a Bcx<'a>) -> &'a Bcx<'a> {
+    return alloc(bcx.fcx.arena);
+}
+
+fn g(fcx : &Fcx) {
+    let bcx = Bcx { fcx: fcx };
+    let bcx2 = h(&bcx);
+    unsafe {
+        libc::free(mem::transmute(bcx2));
+    }
+}
+
+fn f(ccx : &Ccx) {
+    let a = Arena(());
+    let fcx = Fcx { arena: &a, ccx: ccx };
+    return g(&fcx);
+}
+
+pub fn main() {
+    let ccx = Ccx { x: 0 };
+    f(&ccx);
+}
diff --git a/tests/run-pass/vecs.rs b/tests/run-pass/vecs.rs
new file mode 100644 (file)
index 0000000..9a8912a
--- /dev/null
@@ -0,0 +1,52 @@
+//ignore-msvc
+
+fn make_vec() -> Vec<u8> {
+    let mut v = Vec::with_capacity(4);
+    v.push(1);
+    v.push(2);
+    v
+}
+
+fn make_vec_macro() -> Vec<u8> {
+    vec![1, 2]
+}
+
+fn make_vec_macro_repeat() -> Vec<u8> {
+    vec![42; 5]
+}
+
+fn make_vec_macro_repeat_zeroed() -> Vec<u8> {
+    vec![0; 7]
+}
+
+fn vec_into_iter() -> u8 {
+    vec![1, 2, 3, 4]
+        .into_iter()
+        .map(|x| x * x)
+        .fold(0, |x, y| x + y)
+}
+
+fn vec_into_iter_zst() -> usize {
+    vec![[0u64; 0], [0u64; 0]]
+        .into_iter()
+        .map(|x| x.len())
+        .sum()
+}
+
+fn vec_reallocate() -> Vec<u8> {
+    let mut v = vec![1, 2];
+    v.push(3);
+    v.push(4);
+    v.push(5);
+    v
+}
+
+fn main() {
+    assert_eq!(vec_reallocate().len(), 5);
+    assert_eq!(vec_into_iter(), 30);
+    assert_eq!(vec_into_iter_zst(), 0);
+    assert_eq!(make_vec().capacity(), 4);
+    assert_eq!(make_vec_macro(), [1, 2]);
+    assert_eq!(make_vec_macro_repeat(), [42; 5]);
+    assert_eq!(make_vec_macro_repeat_zeroed(), [0; 7]);
+}