From 7bbf914078fe3124bc077ce4a52b793c93086c4d Mon Sep 17 00:00:00 2001 From: Alan Egerton Date: Fri, 10 Jun 2022 16:26:00 +0100 Subject: [PATCH 1/5] Clarify `#[derive(PartialEq)]` on enums Fixes #97945 --- library/core/src/cmp.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs index f281e8429c693..7884e302d983b 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`? /// From 915f09181927e746ab693c12c0747cfa47b9fc9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 6 Jun 2022 00:00:00 +0000 Subject: [PATCH 2/5] Remove duplicated implementations of borrowed locals analysis --- .../src/impls/borrowed_locals.rs | 20 +++++ compiler/rustc_mir_dataflow/src/impls/mod.rs | 1 + .../src/dead_store_elimination.rs | 74 ++----------------- compiler/rustc_mir_transform/src/dest_prop.rs | 67 +---------------- 4 files changed, 29 insertions(+), 133 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index 4981ab5152cd7..b5de222c3eb82 100644 --- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs +++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs @@ -145,3 +145,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 From 777bf84f6c2033db6251df1220dae5a39d4598f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 7 Jun 2022 00:00:00 +0000 Subject: [PATCH 3/5] Merge arms in borrowed locals transfer function --- compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs index b5de222c3eb82..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); } From 84a13a28b749eb4765da0918131a47461fb99e3d Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Sun, 12 Jun 2022 17:27:36 +0900 Subject: [PATCH 4/5] use `create_snapshot_for_diagnostic` instead of `clone` --- compiler/rustc_expand/src/mbe/macro_rules.rs | 2 +- compiler/rustc_parse/src/parser/diagnostics.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index b86304ba6b1b1..8cb938f40af78 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_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 From 2f47edbf09561dce8628248d228abc2c240f4e57 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 9 Jun 2022 16:06:27 +0000 Subject: [PATCH 5/5] Fix some test annotations These are necessary for running the rustc test suite with cg_clif --- src/test/ui/asm/x86_64/issue-82869.rs | 1 + src/test/ui/asm/x86_64/issue-82869.stderr | 6 +++--- src/test/ui/drop/repeat-drop.rs | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) 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