Merge pull request #769 from RalfJung/rustup

Rustup
This commit is contained in:
Ralf Jung 2019-06-13 09:50:54 +02:00 committed by GitHub
commit 965160d4d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 69 additions and 55 deletions

View File

@ -55,7 +55,11 @@ Install Miri via `rustup`:
rustup component add miri
```
If `rustup` says the `miri` component is unavailable, that's because not all nightly releases come with all tools. Check out [this website](https://rust-lang.github.io/rustup-components-history) to determine a nightly version that comes with Miri and install that, e.g. using `rustup install nightly-2019-03-28`.
If `rustup` says the `miri` component is unavailable, that's because not all
nightly releases come with all tools. Check out
[this website](https://rust-lang.github.io/rustup-components-history) to
determine a nightly version that comes with Miri and install that, e.g. using
`rustup install nightly-2019-03-28`.
Now you can run your project in Miri:
@ -131,7 +135,17 @@ able to just `cargo build` Miri.
In case this fails, your nightly might be incompatible with Miri master. The
`rust-version` file contains the commit hash of rustc that Miri is currently
tested against; you can use that to find a nightly that works or you might have
to wait for the next nightly to get released.
to wait for the next nightly to get released. You can also use
[`rustup-toolchain-install-master`](https://github.com/kennytm/rustup-toolchain-install-master)
to install that exact version of rustc as a toolchain:
```
rustup-toolchain-install-master $(cat rust-version) -c rust-src
```
Another common problem is outdated dependencies: Miri does not come with a
lockfile (it cannot, due to how it gets embedded into the rustc build). So you
have to run `cargo update` every now and then yourself to make sure you are
using the latest versions of everything (which is what gets tested on CI).
### Testing the Miri driver
[testing-miri]: #testing-the-miri-driver

View File

@ -1 +1 @@
8e948df707ea8a3c88c65bf2ffdcb2f1cf5491be
d8f50ab0ea6c529c24e575279acc72093caeb679

View File

@ -43,8 +43,8 @@ impl rustc_driver::Callbacks for MiriCompilerCalls {
compiler.session().abort_if_errors();
compiler.global_ctxt().unwrap().peek_mut().enter(|tcx| {
if std::env::args().any(|arg| arg == "--test") {
struct Visitor<'a, 'tcx: 'a>(TyCtxt<'a, 'tcx, 'tcx>);
impl<'a, 'tcx: 'a, 'hir> itemlikevisit::ItemLikeVisitor<'hir> for Visitor<'a, 'tcx> {
struct Visitor<'tcx>(TyCtxt<'tcx, '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.node {
if i.attrs.iter().any(|attr| attr.check_name(syntax::symbol::sym::test)) {

View File

@ -9,8 +9,8 @@ use rand::RngCore;
use crate::*;
impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn find_fn(
&mut self,
instance: ty::Instance<'tcx>,
@ -930,8 +930,8 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
}
}
fn gen_random<'a, 'mir, 'tcx>(
this: &mut MiriEvalContext<'a, 'mir, 'tcx>,
fn gen_random<'mir, 'tcx>(
this: &mut MiriEvalContext<'mir, 'tcx>,
len: usize,
dest: Scalar<Tag>,
) -> InterpResult<'tcx> {

View File

@ -5,9 +5,9 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
use crate::*;
impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
/// Gets an instance for a path.
fn resolve_path(&self, path: &[&str]) -> InterpResult<'tcx, ty::Instance<'tcx>> {
let this = self.eval_context_ref();
@ -119,24 +119,24 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
/// Visiting the memory covered by a `MemPlace`, being aware of
/// whether we are inside an `UnsafeCell` or not.
struct UnsafeCellVisitor<'ecx, 'a, 'mir, 'tcx, F>
struct UnsafeCellVisitor<'ecx, 'mir, 'tcx, F>
where F: FnMut(MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx>
{
ecx: &'ecx MiriEvalContext<'a, 'mir, 'tcx>,
ecx: &'ecx MiriEvalContext<'mir, 'tcx>,
unsafe_cell_action: F,
}
impl<'ecx, 'a, 'mir, 'tcx, F>
ValueVisitor<'a, 'mir, 'tcx, Evaluator<'tcx>>
impl<'ecx, 'mir, 'tcx, F>
ValueVisitor<'mir, 'tcx, Evaluator<'tcx>>
for
UnsafeCellVisitor<'ecx, 'a, 'mir, 'tcx, F>
UnsafeCellVisitor<'ecx, 'mir, 'tcx, F>
where
F: FnMut(MPlaceTy<'tcx, Tag>) -> InterpResult<'tcx>
{
type V = MPlaceTy<'tcx, Tag>;
#[inline(always)]
fn ecx(&self) -> &MiriEvalContext<'a, 'mir, 'tcx> {
fn ecx(&self) -> &MiriEvalContext<'mir, 'tcx> {
&self.ecx
}

View File

@ -9,8 +9,8 @@ use crate::{
OperatorEvalContextExt
};
impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn call_intrinsic(
&mut self,
instance: ty::Instance<'tcx>,

View File

@ -71,11 +71,11 @@ pub struct MiriConfig {
}
// Used by priroda.
pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub fn create_ecx<'mir, 'tcx: 'mir>(
tcx: TyCtxt<'tcx, 'tcx>,
main_id: DefId,
config: MiriConfig,
) -> InterpResult<'tcx, InterpretCx<'a, 'mir, 'tcx, Evaluator<'tcx>>> {
) -> InterpResult<'tcx, InterpretCx<'mir, 'tcx, Evaluator<'tcx>>> {
let mut ecx = InterpretCx::new(
tcx.at(syntax::source_map::DUMMY_SP),
ty::ParamEnv::reveal_all(),
@ -211,8 +211,8 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
Ok(ecx)
}
pub fn eval_main<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
pub fn eval_main<'tcx>(
tcx: TyCtxt<'tcx, 'tcx>,
main_id: DefId,
config: MiriConfig,
) {
@ -364,25 +364,25 @@ impl<'tcx> Evaluator<'tcx> {
// FIXME: rustc issue <https://github.com/rust-lang/rust/issues/47131>.
#[allow(dead_code)]
type MiriEvalContext<'a, 'mir, 'tcx> = InterpretCx<'a, 'mir, 'tcx, Evaluator<'tcx>>;
type MiriEvalContext<'mir, 'tcx> = InterpretCx<'mir, 'tcx, Evaluator<'tcx>>;
// A little trait that's useful to be inherited by extension traits.
pub trait MiriEvalContextExt<'a, 'mir, 'tcx> {
fn eval_context_ref(&self) -> &MiriEvalContext<'a, 'mir, 'tcx>;
fn eval_context_mut(&mut self) -> &mut MiriEvalContext<'a, 'mir, 'tcx>;
pub trait MiriEvalContextExt<'mir, 'tcx> {
fn eval_context_ref(&self) -> &MiriEvalContext<'mir, 'tcx>;
fn eval_context_mut(&mut self) -> &mut MiriEvalContext<'mir, 'tcx>;
}
impl<'a, 'mir, 'tcx> MiriEvalContextExt<'a, 'mir, 'tcx> for MiriEvalContext<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> MiriEvalContextExt<'mir, 'tcx> for MiriEvalContext<'mir, 'tcx> {
#[inline(always)]
fn eval_context_ref(&self) -> &MiriEvalContext<'a, 'mir, 'tcx> {
fn eval_context_ref(&self) -> &MiriEvalContext<'mir, 'tcx> {
self
}
#[inline(always)]
fn eval_context_mut(&mut self) -> &mut MiriEvalContext<'a, 'mir, 'tcx> {
fn eval_context_mut(&mut self) -> &mut MiriEvalContext<'mir, 'tcx> {
self
}
}
impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
type MemoryKinds = MiriMemoryKind;
type FrameExtra = stacked_borrows::CallId;
@ -395,14 +395,14 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
const STATIC_KIND: Option<MiriMemoryKind> = Some(MiriMemoryKind::Static);
#[inline(always)]
fn enforce_validity(ecx: &InterpretCx<'a, 'mir, 'tcx, Self>) -> bool {
fn enforce_validity(ecx: &InterpretCx<'mir, 'tcx, Self>) -> bool {
ecx.machine.validate
}
/// Returns `Ok()` when the function was handled; fail otherwise.
#[inline(always)]
fn find_fn(
ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: Option<PlaceTy<'tcx, Tag>>,
@ -413,7 +413,7 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
#[inline(always)]
fn call_intrinsic(
ecx: &mut rustc_mir::interpret::InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &mut rustc_mir::interpret::InterpretCx<'mir, 'tcx, Self>,
instance: ty::Instance<'tcx>,
args: &[OpTy<'tcx, Tag>],
dest: PlaceTy<'tcx, Tag>,
@ -423,7 +423,7 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
#[inline(always)]
fn ptr_op(
ecx: &rustc_mir::interpret::InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &rustc_mir::interpret::InterpretCx<'mir, 'tcx, Self>,
bin_op: mir::BinOp,
left: ImmTy<'tcx, Tag>,
right: ImmTy<'tcx, Tag>,
@ -432,7 +432,7 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
}
fn box_alloc(
ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
dest: PlaceTy<'tcx, Tag>,
) -> InterpResult<'tcx> {
trace!("box_alloc for {:?}", dest.layout.ty);
@ -475,7 +475,7 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
fn find_foreign_static(
def_id: DefId,
tcx: TyCtxtAt<'a, 'tcx, 'tcx>,
tcx: TyCtxtAt<'tcx, 'tcx>,
) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
let attrs = tcx.get_attrs(def_id);
let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) {
@ -498,7 +498,7 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
}
#[inline(always)]
fn before_terminator(_ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>) -> InterpResult<'tcx>
fn before_terminator(_ecx: &mut InterpretCx<'mir, 'tcx, Self>) -> InterpResult<'tcx>
{
// We are not interested in detecting loops.
Ok(())
@ -550,7 +550,7 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
#[inline(always)]
fn retag(
ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
kind: mir::RetagKind,
place: PlaceTy<'tcx, Tag>,
) -> InterpResult<'tcx> {
@ -568,14 +568,14 @@ impl<'a, 'mir, 'tcx> Machine<'a, 'mir, 'tcx> for Evaluator<'tcx> {
#[inline(always)]
fn stack_push(
ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
) -> InterpResult<'tcx, stacked_borrows::CallId> {
Ok(ecx.memory().extra.borrow_mut().new_call())
}
#[inline(always)]
fn stack_pop(
ecx: &mut InterpretCx<'a, 'mir, 'tcx, Self>,
ecx: &mut InterpretCx<'mir, 'tcx, Self>,
extra: stacked_borrows::CallId,
) -> InterpResult<'tcx> {
Ok(ecx.memory().extra.borrow_mut().end_call(extra))

View File

@ -33,7 +33,7 @@ pub trait EvalContextExt<'tcx> {
) -> InterpResult<'tcx, Scalar<Tag>>;
}
impl<'a, 'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
fn ptr_op(
&self,
bin_op: mir::BinOp,

View File

@ -519,8 +519,8 @@ impl AllocationExtra<Tag> for Stacks {
/// Retagging/reborrowing. There is some policy in here, such as which permissions
/// to grant for which references, and when to add protectors.
impl<'a, 'mir, 'tcx> EvalContextPrivExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
trait EvalContextPrivExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> EvalContextPrivExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn reborrow(
&mut self,
place: MPlaceTy<'tcx, Tag>,
@ -599,8 +599,8 @@ trait EvalContextPrivExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
}
}
impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn retag(
&mut self,
kind: RetagKind,
@ -643,19 +643,19 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a,
visitor.visit_value(place)?;
// The actual visitor.
struct RetagVisitor<'ecx, 'a, 'mir, 'tcx> {
ecx: &'ecx mut MiriEvalContext<'a, 'mir, 'tcx>,
struct RetagVisitor<'ecx, 'mir, 'tcx> {
ecx: &'ecx mut MiriEvalContext<'mir, 'tcx>,
kind: RetagKind,
}
impl<'ecx, 'a, 'mir, 'tcx>
MutValueVisitor<'a, 'mir, 'tcx, Evaluator<'tcx>>
impl<'ecx, 'mir, 'tcx>
MutValueVisitor<'mir, 'tcx, Evaluator<'tcx>>
for
RetagVisitor<'ecx, 'a, 'mir, 'tcx>
RetagVisitor<'ecx, 'mir, 'tcx>
{
type V = MPlaceTy<'tcx, Tag>;
#[inline(always)]
fn ecx(&mut self) -> &mut MiriEvalContext<'a, 'mir, 'tcx> {
fn ecx(&mut self) -> &mut MiriEvalContext<'mir, 'tcx> {
&mut self.ecx
}

View File

@ -129,8 +129,8 @@ impl<'tcx> TlsData<'tcx> {
}
}
impl<'a, 'mir, 'tcx> EvalContextExt<'a, 'mir, 'tcx> for crate::MiriEvalContext<'a, 'mir, 'tcx> {}
pub trait EvalContextExt<'a, 'mir, 'tcx: 'a+'mir>: crate::MiriEvalContextExt<'a, 'mir, 'tcx> {
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn run_tls_dtors(&mut self) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let mut dtor = this.machine.tls.fetch_tls_dtor(None, &*this.tcx);