Skip to content
2 changes: 1 addition & 1 deletion compiler/rustc_expand/src/mbe/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
28 changes: 21 additions & 7 deletions compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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<Local> {
struct Borrowed(BitSet<Local>);

impl GenKill<Local> 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
}
1 change: 1 addition & 0 deletions compiler/rustc_mir_dataflow/src/impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
74 changes: 6 additions & 68 deletions compiler/rustc_mir_transform/src/dead_store_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Local>) {
let mut live = MaybeTransitiveLiveLocals::new(borrowed)
.into_engine(tcx, body)
Expand Down Expand Up @@ -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<Local> {
let mut b = BorrowedLocals(BitSet::new_empty(body.local_decls.len()));
b.visit_body(body);
b.0
}

struct BorrowedLocals(BitSet<Local>);

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 {
Expand All @@ -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);
}
}
67 changes: 2 additions & 65 deletions compiler/rustc_mir_transform/src/dest_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -805,7 +805,7 @@ fn find_candidates<'tcx>(body: &Body<'tcx>) -> Vec<CandidateAssignment<'tcx>> {
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);
Expand Down Expand Up @@ -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<Local> {
let mut visitor = BorrowCollector { locals: BitSet::new_empty(body.local_decls.len()) };
visitor.visit_body(body);
visitor.locals
}

struct BorrowCollector {
locals: BitSet<Local>,
}

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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<UnmatchedBrace>,
}
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions library/core/src/cmp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`?
///
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/asm/x86_64/issue-82869.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// needs-asm-support
// only-x86_64
// Make sure rustc doesn't ICE on asm! for a foreign architecture.

Expand Down
6 changes: 3 additions & 3 deletions src/test/ui/asm/x86_64/issue-82869.stderr
Original file line number Diff line number Diff line change
@@ -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") {
| _________________________________________________________^
Expand Down
1 change: 1 addition & 0 deletions src/test/ui/drop/repeat-drop.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// run-pass
// needs-unwind
// ignore-wasm32-bare no unwinding panic
// ignore-avr no unwinding panic
// ignore-nvptx64 no unwinding panic
Expand Down