diff options
| author | bors <bors@rust-lang.org> | 2020-10-04 04:33:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-10-04 04:33:28 +0000 |
| commit | 2251766944f355a039e67aeb13ab630b2d46bf9b (patch) | |
| tree | 255a2666dc4671287f122208c30df66693e17855 /compiler/rustc_mir | |
| parent | 4cf3dc19a1e59ffdebe3d8ca106e5b7f2d6d212e (diff) | |
| parent | f5db16639713a9a3e6730a59c5a03007557df057 (diff) | |
| download | rust-2251766944f355a039e67aeb13ab630b2d46bf9b.tar.gz rust-2251766944f355a039e67aeb13ab630b2d46bf9b.zip | |
Auto merge of #77517 - JohnTitor:rollup-msbd49e, r=JohnTitor
Rollup of 11 pull requests Successful merges: - #75143 (Use `tracing` spans to trace the entire MIR interp stack) - #75699 (Uplift drop-bounds lint from clippy) - #76768 (Test and reject out-of-bounds shuffle vectors) - #77190 (updated p! macro to accept literals) - #77388 (Add some regression tests) - #77419 (Create E0777 error code for invalid argument in derive) - #77447 (BTreeMap: document DrainFilterInner better) - #77468 (Fix test name) - #77469 (Improve rustdoc error for failed intra-doc link resolution) - #77473 (Make --all-targets in x.py check opt-in) - #77508 (Fix capitalization in blog post name) Failed merges: r? `@ghost`
Diffstat (limited to 'compiler/rustc_mir')
| -rw-r--r-- | compiler/rustc_mir/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/interpret/eval_context.rs | 78 |
2 files changed, 56 insertions, 23 deletions
diff --git a/compiler/rustc_mir/Cargo.toml b/compiler/rustc_mir/Cargo.toml index a6d22243d6d..487668cfa11 100644 --- a/compiler/rustc_mir/Cargo.toml +++ b/compiler/rustc_mir/Cargo.toml @@ -12,7 +12,6 @@ either = "1.5.0" rustc_graphviz = { path = "../rustc_graphviz" } itertools = "0.9" tracing = "0.1" -log_settings = "0.1.1" polonius-engine = "0.12.0" regex = "1" rustc_middle = { path = "../rustc_middle" } diff --git a/compiler/rustc_mir/src/interpret/eval_context.rs b/compiler/rustc_mir/src/interpret/eval_context.rs index f97096984fa..93da6e3d38a 100644 --- a/compiler/rustc_mir/src/interpret/eval_context.rs +++ b/compiler/rustc_mir/src/interpret/eval_context.rs @@ -48,8 +48,41 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> { FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Pointer<M::PointerTag>>, } +// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread +// boundary and dropped in the other thread, it would exit the span in the other thread. +struct SpanGuard(tracing::Span, std::marker::PhantomData<*const u8>); + +impl SpanGuard { + /// By default a `SpanGuard` does nothing. + fn new() -> Self { + Self(tracing::Span::none(), std::marker::PhantomData) + } + + /// If a span is entered, we exit the previous span (if any, normally none) and enter the + /// new span. This is mainly so we don't have to use `Option` for the `tracing_span` field of + /// `Frame` by creating a dummy span to being with and then entering it once the frame has + /// been pushed. + fn enter(&mut self, span: tracing::Span) { + // This executes the destructor on the previous instance of `SpanGuard`, ensuring that + // we never enter or exit more spans than vice versa. Unless you `mem::leak`, then we + // can't protect the tracing stack, but that'll just lead to weird logging, no actual + // problems. + *self = Self(span, std::marker::PhantomData); + self.0.with_subscriber(|(id, dispatch)| { + dispatch.enter(id); + }); + } +} + +impl Drop for SpanGuard { + fn drop(&mut self) { + self.0.with_subscriber(|(id, dispatch)| { + dispatch.exit(id); + }); + } +} + /// A stack frame. -#[derive(Clone)] pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { //////////////////////////////////////////////////////////////////////////////// // Function and callsite information @@ -80,6 +113,11 @@ pub struct Frame<'mir, 'tcx, Tag = (), Extra = ()> { /// can either directly contain `Scalar` or refer to some part of an `Allocation`. pub locals: IndexVec<mir::Local, LocalState<'tcx, Tag>>, + /// The span of the `tracing` crate is stored here. + /// When the guard is dropped, the span is exited. This gives us + /// a full stack trace on all tracing statements. + tracing_span: SpanGuard, + //////////////////////////////////////////////////////////////////////////////// // Current position within the function //////////////////////////////////////////////////////////////////////////////// @@ -184,6 +222,7 @@ impl<'mir, 'tcx, Tag> Frame<'mir, 'tcx, Tag> { locals: self.locals, loc: self.loc, extra, + tracing_span: self.tracing_span, } } } @@ -637,11 +676,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return_place: Option<PlaceTy<'tcx, M::PointerTag>>, return_to_block: StackPopCleanup, ) -> InterpResult<'tcx> { - if !self.stack().is_empty() { - info!("PAUSING({}) {}", self.frame_idx(), self.frame().instance); - } - ::log_settings::settings().indentation += 1; - // first push a stack frame so we have access to the local substs let pre_frame = Frame { body, @@ -652,6 +686,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // all methods actually know about the frame locals: IndexVec::new(), instance, + tracing_span: SpanGuard::new(), extra: (), }; let frame = M::init_frame_extra(self, pre_frame)?; @@ -696,7 +731,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.frame_mut().locals = locals; M::after_stack_push(self)?; self.frame_mut().loc = Ok(mir::Location::START); - info!("ENTERING({}) {}", self.frame_idx(), self.frame().instance); + + let span = info_span!("frame", "{}", instance); + self.frame_mut().tracing_span.enter(span); Ok(()) } @@ -747,10 +784,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { /// cause us to continue unwinding. pub(super) fn pop_stack_frame(&mut self, unwinding: bool) -> InterpResult<'tcx> { info!( - "LEAVING({}) {} (unwinding = {})", - self.frame_idx(), - self.frame().instance, - unwinding + "popping stack frame ({})", + if unwinding { "during unwinding" } else { "returning from function" } ); // Sanity check `unwinding`. @@ -766,7 +801,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { throw_ub_format!("unwinding past the topmost frame of the stack"); } - ::log_settings::settings().indentation -= 1; let frame = self.stack_mut().pop().expect("tried to pop a stack frame, but there were none"); @@ -823,15 +857,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - if !self.stack().is_empty() { - info!( - "CONTINUING({}) {} (unwinding = {})", - self.frame_idx(), - self.frame().instance, - unwinding - ); - } - Ok(()) } @@ -995,7 +1020,16 @@ where { fn hash_stable(&self, hcx: &mut StableHashingContext<'ctx>, hasher: &mut StableHasher) { // Exhaustive match on fields to make sure we forget no field. - let Frame { body, instance, return_to_block, return_place, locals, loc, extra } = self; + let Frame { + body, + instance, + return_to_block, + return_place, + locals, + loc, + extra, + tracing_span: _, + } = self; body.hash_stable(hcx, hasher); instance.hash_stable(hcx, hasher); return_to_block.hash_stable(hcx, hasher); |
