diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 04af1eaf67b6d..a66d36aaf72ee 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -123,7 +123,7 @@ impl<'a> ParserAnyMacro<'a> { is_trailing_mac, is_local, } = *self; - let snapshot = &mut parser.clone(); + let snapshot = &mut parser.create_snapshot_for_diagnostic(); let fragment = match parse_ast_fragment(parser, kind) { Ok(f) => f, Err(err) => { diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 4981ab5152cd7..627fe3f7f576b 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -85,13 +85,7 @@ where self.super_rvalue(rvalue, location); match rvalue { - mir::Rvalue::AddressOf(_mt, borrowed_place) => { - if !borrowed_place.is_indirect() { - self.trans.gen(borrowed_place.local); - } - } - - mir::Rvalue::Ref(_, _kind, borrowed_place) => { + mir::Rvalue::AddressOf(_, borrowed_place) | mir::Rvalue::Ref(_, _, borrowed_place) => { if !borrowed_place.is_indirect() { self.trans.gen(borrowed_place.local); } @@ -145,3 +139,23 @@ where } } } + +/// The set of locals that are borrowed at some point in the MIR body. +pub fn borrowed_locals(body: &Body<'_>) -> BitSet { + struct Borrowed(BitSet); + + impl GenKill for Borrowed { + #[inline] + fn gen(&mut self, elem: Local) { + self.0.gen(elem) + } + #[inline] + fn kill(&mut self, _: Local) { + // Ignore borrow invalidation. + } + } + + let mut borrowed = Borrowed(BitSet::new_empty(body.local_decls.len())); + TransferFunction { trans: &mut borrowed }.visit_body(body); + borrowed.0 +} diff --git a/compiler/rustc_mir_dataflow/src/impls/mod.rs b/compiler/rustc_mir_dataflow/src/impls/mod.rs index 41cf43fc8e186..af6a1bb1545ea 100644 --- a/compiler/rustc_mir_dataflow/src/impls/mod.rs +++ b/compiler/rustc_mir_dataflow/src/impls/mod.rs @@ -23,6 +23,7 @@ mod init_locals; mod liveness; mod storage_liveness; +pub use self::borrowed_locals::borrowed_locals; pub use self::borrowed_locals::MaybeBorrowedLocals; pub use self::init_locals::MaybeInitializedLocals; pub use self::liveness::MaybeLiveLocals; diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs index 779f3c778156b..28f3790914b38 100644 --- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs +++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs @@ -13,16 +13,15 @@ //! use rustc_index::bit_set::BitSet; -use rustc_middle::{ - mir::{visit::Visitor, *}, - ty::TyCtxt, -}; -use rustc_mir_dataflow::{impls::MaybeTransitiveLiveLocals, Analysis}; +use rustc_middle::mir::*; +use rustc_middle::ty::TyCtxt; +use rustc_mir_dataflow::impls::{borrowed_locals, MaybeTransitiveLiveLocals}; +use rustc_mir_dataflow::Analysis; /// Performs the optimization on the body /// /// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It -/// can be generated via the [`get_borrowed_locals`] function. +/// can be generated via the [`borrowed_locals`] function. pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitSet) { let mut live = MaybeTransitiveLiveLocals::new(borrowed) .into_engine(tcx, body) @@ -73,67 +72,6 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS } } -pub fn get_borrowed_locals(body: &Body<'_>) -> BitSet { - let mut b = BorrowedLocals(BitSet::new_empty(body.local_decls.len())); - b.visit_body(body); - b.0 -} - -struct BorrowedLocals(BitSet); - -impl<'tcx> Visitor<'tcx> for BorrowedLocals { - fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, loc: Location) { - self.super_rvalue(rvalue, loc); - match rvalue { - Rvalue::AddressOf(_, borrowed_place) | Rvalue::Ref(_, _, borrowed_place) => { - if !borrowed_place.is_indirect() { - self.0.insert(borrowed_place.local); - } - } - - Rvalue::Cast(..) - | Rvalue::ShallowInitBox(..) - | Rvalue::Use(..) - | Rvalue::Repeat(..) - | Rvalue::Len(..) - | Rvalue::BinaryOp(..) - | Rvalue::CheckedBinaryOp(..) - | Rvalue::NullaryOp(..) - | Rvalue::UnaryOp(..) - | Rvalue::Discriminant(..) - | Rvalue::Aggregate(..) - | Rvalue::ThreadLocalRef(..) => {} - } - } - - fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { - self.super_terminator(terminator, location); - - match terminator.kind { - TerminatorKind::Drop { place: dropped_place, .. } => { - if !dropped_place.is_indirect() { - self.0.insert(dropped_place.local); - } - } - - TerminatorKind::Abort - | TerminatorKind::DropAndReplace { .. } - | TerminatorKind::Assert { .. } - | TerminatorKind::Call { .. } - | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::GeneratorDrop - | TerminatorKind::Goto { .. } - | TerminatorKind::Resume - | TerminatorKind::Return - | TerminatorKind::SwitchInt { .. } - | TerminatorKind::Unreachable - | TerminatorKind::Yield { .. } - | TerminatorKind::InlineAsm { .. } => {} - } - } -} - pub struct DeadStoreElimination; impl<'tcx> MirPass<'tcx> for DeadStoreElimination { @@ -142,7 +80,7 @@ impl<'tcx> MirPass<'tcx> for DeadStoreElimination { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let borrowed = get_borrowed_locals(body); + let borrowed = borrowed_locals(body); eliminate(tcx, body, &borrowed); } } diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 182dd6f379cc1..84c7aada5e57f 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -104,7 +104,7 @@ use rustc_middle::mir::{ Rvalue, Statement, StatementKind, Terminator, TerminatorKind, }; use rustc_middle::ty::TyCtxt; -use rustc_mir_dataflow::impls::{MaybeInitializedLocals, MaybeLiveLocals}; +use rustc_mir_dataflow::impls::{borrowed_locals, MaybeInitializedLocals, MaybeLiveLocals}; use rustc_mir_dataflow::Analysis; // Empirical measurements have resulted in some observations: @@ -805,7 +805,7 @@ fn find_candidates<'tcx>(body: &Body<'tcx>) -> Vec> { let mut visitor = FindAssignments { body, candidates: Vec::new(), - ever_borrowed_locals: ever_borrowed_locals(body), + ever_borrowed_locals: borrowed_locals(body), locals_used_as_array_index: locals_used_as_array_index(body), }; visitor.visit_body(body); @@ -886,69 +886,6 @@ fn is_local_required(local: Local, body: &Body<'_>) -> bool { } } -/// Walks MIR to find all locals that have their address taken anywhere. -fn ever_borrowed_locals(body: &Body<'_>) -> BitSet { - let mut visitor = BorrowCollector { locals: BitSet::new_empty(body.local_decls.len()) }; - visitor.visit_body(body); - visitor.locals -} - -struct BorrowCollector { - locals: BitSet, -} - -impl<'tcx> Visitor<'tcx> for BorrowCollector { - fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) { - self.super_rvalue(rvalue, location); - - match rvalue { - Rvalue::AddressOf(_, borrowed_place) | Rvalue::Ref(_, _, borrowed_place) => { - if !borrowed_place.is_indirect() { - self.locals.insert(borrowed_place.local); - } - } - - Rvalue::Cast(..) - | Rvalue::ShallowInitBox(..) - | Rvalue::Use(..) - | Rvalue::Repeat(..) - | Rvalue::Len(..) - | Rvalue::BinaryOp(..) - | Rvalue::CheckedBinaryOp(..) - | Rvalue::NullaryOp(..) - | Rvalue::UnaryOp(..) - | Rvalue::Discriminant(..) - | Rvalue::Aggregate(..) - | Rvalue::ThreadLocalRef(..) => {} - } - } - - fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) { - self.super_terminator(terminator, location); - - match terminator.kind { - TerminatorKind::Drop { place: dropped_place, .. } - | TerminatorKind::DropAndReplace { place: dropped_place, .. } => { - self.locals.insert(dropped_place.local); - } - - TerminatorKind::Abort - | TerminatorKind::Assert { .. } - | TerminatorKind::Call { .. } - | TerminatorKind::FalseEdge { .. } - | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::GeneratorDrop - | TerminatorKind::Goto { .. } - | TerminatorKind::Resume - | TerminatorKind::Return - | TerminatorKind::SwitchInt { .. } - | TerminatorKind::Unreachable - | TerminatorKind::Yield { .. } - | TerminatorKind::InlineAsm { .. } => {} - } - } -} - /// `PlaceElem::Index` only stores a `Local`, so we can't replace that with a full `Place`. /// /// Collect locals used as indices so we don't generate candidates that are impossible to apply diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index a4cdfdf55f9df..6a44f5d6653ef 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -336,7 +336,7 @@ struct InInTypo { // SnapshotParser is used to create a snapshot of the parser // without causing duplicate errors being emitted when the `Parser` // is dropped. -pub(super) struct SnapshotParser<'a> { +pub struct SnapshotParser<'a> { parser: Parser<'a>, unclosed_delims: Vec, } @@ -392,7 +392,7 @@ impl<'a> Parser<'a> { } /// Create a snapshot of the `Parser`. - pub(super) fn create_snapshot_for_diagnostic(&self) -> SnapshotParser<'a> { + pub fn create_snapshot_for_diagnostic(&self) -> SnapshotParser<'a> { let mut snapshot = self.clone(); let unclosed_delims = self.unclosed_delims.clone(); // Clear `unclosed_delims` in snapshot to avoid diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index 81aed8afd5b51..064675ee7cf24 100644 --- a/library/core/src/cmp.rs +++ b/library/core/src/cmp.rs @@ -61,8 +61,8 @@ use self::Ordering::*; /// /// This trait can be used with `#[derive]`. When `derive`d on structs, two /// instances are equal if all fields are equal, and not equal if any fields -/// are not equal. When `derive`d on enums, each variant is equal to itself -/// and not equal to the other variants. +/// are not equal. When `derive`d on enums, two instances are equal if they +/// are the same variant and all fields are equal. /// /// ## How can I implement `PartialEq`? /// diff --git a/src/test/ui/asm/x86_64/issue-82869.rs b/src/test/ui/asm/x86_64/issue-82869.rs index 3e632eaf88dda..67933666eb5d3 100644 --- a/src/test/ui/asm/x86_64/issue-82869.rs +++ b/src/test/ui/asm/x86_64/issue-82869.rs @@ -1,3 +1,4 @@ +// needs-asm-support // only-x86_64 // Make sure rustc doesn't ICE on asm! for a foreign architecture. diff --git a/src/test/ui/asm/x86_64/issue-82869.stderr b/src/test/ui/asm/x86_64/issue-82869.stderr index 42be1b6de725a..3cf9d6d1c1c00 100644 --- a/src/test/ui/asm/x86_64/issue-82869.stderr +++ b/src/test/ui/asm/x86_64/issue-82869.stderr @@ -1,17 +1,17 @@ error: invalid register class `vreg`: unknown register class - --> $DIR/issue-82869.rs:10:32 + --> $DIR/issue-82869.rs:11:32 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^^ error: invalid register class `vreg`: unknown register class - --> $DIR/issue-82869.rs:10:45 + --> $DIR/issue-82869.rs:11:45 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | ^^^^^^^^^^ error: invalid register `d0`: unknown register - --> $DIR/issue-82869.rs:10:57 + --> $DIR/issue-82869.rs:11:57 | LL | asm!("add {:d}, {:d}, d0", out(vreg) c, in(vreg) a, in("d0") { | _________________________________________________________^ diff --git a/src/test/ui/drop/repeat-drop.rs b/src/test/ui/drop/repeat-drop.rs index 03e832adb3b3b..a43612e5d8587 100644 --- a/src/test/ui/drop/repeat-drop.rs +++ b/src/test/ui/drop/repeat-drop.rs @@ -1,4 +1,5 @@ // run-pass +// needs-unwind // ignore-wasm32-bare no unwinding panic // ignore-avr no unwinding panic // ignore-nvptx64 no unwinding panic