diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs index 26a090f5579ce..96f48840468e5 100644 --- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs +++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs @@ -1,7 +1,7 @@ use std::collections::VecDeque; use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::mir::visit::{MirVisitable, PlaceContext, Visitor}; +use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{self, Body, Local, Location}; use rustc_middle::ty::{RegionVid, TyCtxt}; @@ -45,7 +45,22 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { let block_data = &self.body[p.block]; - match self.def_use(p, block_data.visitable(p.statement_index)) { + let mut visitor = DefUseVisitor { + body: self.body, + tcx: self.tcx, + region_vid: self.region_vid, + def_use_result: None, + }; + + let is_statement = p.statement_index < block_data.statements.len(); + + if is_statement { + visitor.visit_statement(&block_data.statements[p.statement_index], p); + } else { + visitor.visit_terminator(block_data.terminator.as_ref().unwrap(), p); + } + + match visitor.def_use_result { Some(DefUseResult::Def) => {} Some(DefUseResult::UseLive { local }) => { @@ -57,7 +72,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { } None => { - if p.statement_index < block_data.statements.len() { + if is_statement { queue.push_back(p.successor_within_block()); } else { queue.extend( @@ -77,19 +92,6 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> { None } - - fn def_use(&self, location: Location, thing: &dyn MirVisitable<'tcx>) -> Option { - let mut visitor = DefUseVisitor { - body: self.body, - tcx: self.tcx, - region_vid: self.region_vid, - def_use_result: None, - }; - - thing.apply(location, &mut visitor); - - visitor.def_use_result - } } struct DefUseVisitor<'a, 'tcx> { diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 528da4ca05776..ff493fa65a6ab 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -32,7 +32,6 @@ use tracing::{debug, trace}; pub use self::query::*; use self::visit::TyContext; use crate::mir::interpret::{AllocRange, Scalar}; -use crate::mir::visit::MirVisitable; use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::visit::TypeVisitableExt; @@ -1364,10 +1363,6 @@ impl<'tcx> BasicBlockData<'tcx> { self.terminator.as_mut().expect("invalid terminator state") } - pub fn visitable(&self, index: usize) -> &dyn MirVisitable<'tcx> { - if index < self.statements.len() { &self.statements[index] } else { &self.terminator } - } - /// Does the block have no statements and an unreachable terminator? #[inline] pub fn is_empty_unreachable(&self) -> bool { diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs index 8ad88fbda7c89..193806f238b1d 100644 --- a/compiler/rustc_middle/src/mir/visit.rs +++ b/compiler/rustc_middle/src/mir/visit.rs @@ -270,10 +270,12 @@ macro_rules! make_mir_visitor { fn visit_local( &mut self, - _local: $(& $mutability)? Local, - _context: PlaceContext, - _location: Location, - ) {} + local: $(& $mutability)? Local, + context: PlaceContext, + location: Location, + ) { + self.super_local(local, context, location) + } fn visit_source_scope( &mut self, @@ -292,9 +294,11 @@ macro_rules! make_mir_visitor { super_body!(self, body, $($mutability, true)?); } - fn super_basic_block_data(&mut self, - block: BasicBlock, - data: & $($mutability)? BasicBlockData<'tcx>) { + fn super_basic_block_data( + &mut self, + block: BasicBlock, + data: & $($mutability)? BasicBlockData<'tcx>) + { let BasicBlockData { statements, terminator, @@ -339,24 +343,24 @@ macro_rules! make_mir_visitor { match callee_def { ty::InstanceKind::Item(_def_id) => {} - ty::InstanceKind::Intrinsic(_def_id) | - ty::InstanceKind::VTableShim(_def_id) | - ty::InstanceKind::ReifyShim(_def_id, _) | - ty::InstanceKind::Virtual(_def_id, _) | - ty::InstanceKind::ThreadLocalShim(_def_id) | - ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } | - ty::InstanceKind::ConstructCoroutineInClosureShim { + ty::InstanceKind::Intrinsic(_def_id) + | ty::InstanceKind::VTableShim(_def_id) + | ty::InstanceKind::ReifyShim(_def_id, _) + | ty::InstanceKind::Virtual(_def_id, _) + | ty::InstanceKind::ThreadLocalShim(_def_id) + | ty::InstanceKind::ClosureOnceShim { call_once: _def_id, track_caller: _ } + | ty::InstanceKind::ConstructCoroutineInClosureShim { coroutine_closure_def_id: _def_id, receiver_by_ref: _, - } | - ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) | - ty::InstanceKind::DropGlue(_def_id, None) => {} - - ty::InstanceKind::FnPtrShim(_def_id, ty) | - ty::InstanceKind::DropGlue(_def_id, Some(ty)) | - ty::InstanceKind::CloneShim(_def_id, ty) | - ty::InstanceKind::FnPtrAddrShim(_def_id, ty) | - ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { + } + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, None) + | ty::InstanceKind::DropGlue(_def_id, None) => {} + + ty::InstanceKind::FnPtrShim(_def_id, ty) + | ty::InstanceKind::DropGlue(_def_id, Some(ty)) + | ty::InstanceKind::CloneShim(_def_id, ty) + | ty::InstanceKind::FnPtrAddrShim(_def_id, ty) + | ty::InstanceKind::AsyncDropGlueCtorShim(_def_id, Some(ty)) => { // FIXME(eddyb) use a better `TyContext` here. self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } @@ -368,19 +372,16 @@ macro_rules! make_mir_visitor { } } - fn super_statement(&mut self, - statement: & $($mutability)? Statement<'tcx>, - location: Location) { - let Statement { - source_info, - kind, - } = statement; + fn super_statement( + &mut self, + statement: & $($mutability)? Statement<'tcx>, + location: Location + ) { + let Statement { source_info, kind } = statement; self.visit_source_info(source_info); match kind { - StatementKind::Assign( - box (place, rvalue) - ) => { + StatementKind::Assign(box (place, rvalue)) => { self.visit_assign(place, rvalue, location); } StatementKind::FakeRead(box (_, place)) => { @@ -428,11 +429,13 @@ macro_rules! make_mir_visitor { location ); } - StatementKind::AscribeUserType( - box (place, user_ty), - variance - ) => { - self.visit_ascribe_user_ty(place, $(& $mutability)? *variance, user_ty, location); + StatementKind::AscribeUserType(box (place, user_ty), variance) => { + self.visit_ascribe_user_ty( + place, + $(& $mutability)? *variance, + user_ty, + location + ); } StatementKind::Coverage(coverage) => { self.visit_coverage( @@ -443,7 +446,11 @@ macro_rules! make_mir_visitor { StatementKind::Intrinsic(box ref $($mutability)? intrinsic) => { match intrinsic { NonDivergingIntrinsic::Assume(op) => self.visit_operand(op, location), - NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { src, dst, count }) => { + NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src, + dst, + count + }) => { self.visit_operand(src, location); self.visit_operand(dst, location); self.visit_operand(count, location); @@ -456,10 +463,12 @@ macro_rules! make_mir_visitor { } } - fn super_assign(&mut self, - place: &$($mutability)? Place<'tcx>, - rvalue: &$($mutability)? Rvalue<'tcx>, - location: Location) { + fn super_assign( + &mut self, + place: &$($mutability)? Place<'tcx>, + rvalue: &$($mutability)? Rvalue<'tcx>, + location: Location + ) { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Store), @@ -468,20 +477,22 @@ macro_rules! make_mir_visitor { self.visit_rvalue(rvalue, location); } - fn super_terminator(&mut self, - terminator: &$($mutability)? Terminator<'tcx>, - location: Location) { + fn super_terminator( + &mut self, + terminator: &$($mutability)? Terminator<'tcx>, + location: Location + ) { let Terminator { source_info, kind } = terminator; self.visit_source_info(source_info); match kind { - TerminatorKind::Goto { .. } | - TerminatorKind::UnwindResume | - TerminatorKind::UnwindTerminate(_) | - TerminatorKind::CoroutineDrop | - TerminatorKind::Unreachable | - TerminatorKind::FalseEdge { .. } | - TerminatorKind::FalseUnwind { .. } => {} + TerminatorKind::Goto { .. } + | TerminatorKind::UnwindResume + | TerminatorKind::UnwindTerminate(_) + | TerminatorKind::CoroutineDrop + | TerminatorKind::Unreachable + | TerminatorKind::FalseEdge { .. } + | TerminatorKind::FalseUnwind { .. } => {} TerminatorKind::Return => { // `return` logically moves from the return place `_0`. Note that the place @@ -500,19 +511,11 @@ macro_rules! make_mir_visitor { ); } - TerminatorKind::SwitchInt { - discr, - targets: _ - } => { + TerminatorKind::SwitchInt { discr, targets: _ } => { self.visit_operand(discr, location); } - TerminatorKind::Drop { - place, - target: _, - unwind: _, - replace: _, - } => { + TerminatorKind::Drop { place, target: _, unwind: _, replace: _ } => { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Drop), @@ -541,11 +544,7 @@ macro_rules! make_mir_visitor { ); } - TerminatorKind::TailCall { - func, - args, - fn_span, - } => { + TerminatorKind::TailCall { func, args, fn_span } => { self.visit_span($(& $mutability)? *fn_span); self.visit_operand(func, location); for arg in args { @@ -553,23 +552,12 @@ macro_rules! make_mir_visitor { } }, - TerminatorKind::Assert { - cond, - expected: _, - msg, - target: _, - unwind: _, - } => { + TerminatorKind::Assert { cond, expected: _, msg, target: _, unwind: _ } => { self.visit_operand(cond, location); self.visit_assert_message(msg, location); } - TerminatorKind::Yield { - value, - resume: _, - resume_arg, - drop: _, - } => { + TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => { self.visit_operand(value, location); self.visit_place( resume_arg, @@ -622,9 +610,11 @@ macro_rules! make_mir_visitor { } } - fn super_assert_message(&mut self, - msg: & $($mutability)? AssertMessage<'tcx>, - location: Location) { + fn super_assert_message( + &mut self, + msg: & $($mutability)? AssertMessage<'tcx>, + location: Location + ) { use crate::mir::AssertKind::*; match msg { BoundsCheck { len, index } => { @@ -648,9 +638,11 @@ macro_rules! make_mir_visitor { } } - fn super_rvalue(&mut self, - rvalue: & $($mutability)? Rvalue<'tcx>, - location: Location) { + fn super_rvalue( + &mut self, + rvalue: & $($mutability)? Rvalue<'tcx>, + location: Location + ) { match rvalue { Rvalue::Use(operand) => { self.visit_operand(operand, location); @@ -677,6 +669,7 @@ macro_rules! make_mir_visitor { }; self.visit_place(path, ctx, location); } + Rvalue::CopyForDeref(place) => { self.visit_place( place, @@ -740,8 +733,7 @@ macro_rules! make_mir_visitor { AggregateKind::Array(ty) => { self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); } - AggregateKind::Tuple => { - } + AggregateKind::Tuple => {} AggregateKind::Adt( _adt_def, _variant_index, @@ -751,22 +743,13 @@ macro_rules! make_mir_visitor { ) => { self.visit_args(args, location); } - AggregateKind::Closure( - _, - closure_args - ) => { + AggregateKind::Closure(_, closure_args) => { self.visit_args(closure_args, location); } - AggregateKind::Coroutine( - _, - coroutine_args, - ) => { + AggregateKind::Coroutine(_, coroutine_args) => { self.visit_args(coroutine_args, location); } - AggregateKind::CoroutineClosure( - _, - coroutine_closure_args, - ) => { + AggregateKind::CoroutineClosure(_, coroutine_closure_args) => { self.visit_args(coroutine_closure_args, location); } AggregateKind::RawPtr(ty, _) => { @@ -791,9 +774,11 @@ macro_rules! make_mir_visitor { } } - fn super_operand(&mut self, - operand: & $($mutability)? Operand<'tcx>, - location: Location) { + fn super_operand( + &mut self, + operand: & $($mutability)? Operand<'tcx>, + location: Location + ) { match operand { Operand::Copy(place) => { self.visit_place( @@ -815,28 +800,36 @@ macro_rules! make_mir_visitor { } } - fn super_ascribe_user_ty(&mut self, - place: & $($mutability)? Place<'tcx>, - variance: $(& $mutability)? ty::Variance, - user_ty: & $($mutability)? UserTypeProjection, - location: Location) { + fn super_ascribe_user_ty( + &mut self, + place: & $($mutability)? Place<'tcx>, + variance: $(& $mutability)? ty::Variance, + user_ty: & $($mutability)? UserTypeProjection, + location: Location) + { self.visit_place( place, - PlaceContext::NonUse(NonUseContext::AscribeUserTy($(* &$mutability *)? variance)), + PlaceContext::NonUse( + NonUseContext::AscribeUserTy($(* &$mutability *)? variance) + ), location ); self.visit_user_type_projection(user_ty); } - fn super_coverage(&mut self, - _kind: & $($mutability)? coverage::CoverageKind, - _location: Location) { + fn super_coverage( + &mut self, + _kind: & $($mutability)? coverage::CoverageKind, + _location: Location + ) { } - fn super_retag(&mut self, - _kind: $(& $mutability)? RetagKind, - place: & $($mutability)? Place<'tcx>, - location: Location) { + fn super_retag( + &mut self, + _kind: $(& $mutability)? RetagKind, + place: & $($mutability)? Place<'tcx>, + location: Location + ) { self.visit_place( place, PlaceContext::MutatingUse(MutatingUseContext::Retag), @@ -844,9 +837,11 @@ macro_rules! make_mir_visitor { ); } - fn super_local_decl(&mut self, - local: Local, - local_decl: & $($mutability)? LocalDecl<'tcx>) { + fn super_local_decl( + &mut self, + local: Local, + local_decl: & $($mutability)? LocalDecl<'tcx> + ) { let LocalDecl { mutability: _, ty, @@ -868,6 +863,14 @@ macro_rules! make_mir_visitor { } } + fn super_local( + &mut self, + _local: $(& $mutability)? Local, + _context: PlaceContext, + _location: Location, + ) { + } + fn super_var_debug_info( &mut self, var_debug_info: & $($mutability)? VarDebugInfo<'tcx> @@ -882,7 +885,10 @@ macro_rules! make_mir_visitor { self.visit_source_info(source_info); let location = Location::START; - if let Some(box VarDebugInfoFragment { ref $($mutability)? ty, ref $($mutability)? projection }) = composite { + if let Some(box VarDebugInfoFragment { + ref $($mutability)? ty, + ref $($mutability)? projection + }) = composite { self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); for elem in projection { let ProjectionElem::Field(_, ty) = elem else { bug!() }; @@ -900,10 +906,7 @@ macro_rules! make_mir_visitor { } } - fn super_source_scope( - &mut self, - _scope: $(& $mutability)? SourceScope - ) {} + fn super_source_scope(&mut self, _scope: $(& $mutability)? SourceScope) {} fn super_const_operand( &mut self, @@ -919,8 +922,12 @@ macro_rules! make_mir_visitor { self.visit_span($(& $mutability)? *span); match const_ { Const::Ty(_, ct) => self.visit_ty_const($(&$mutability)? *ct, location), - Const::Val(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), - Const::Unevaluated(_, ty) => self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)), + Const::Val(_, ty) => { + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } + Const::Unevaluated(_, ty) => { + self.visit_ty($(& $mutability)? *ty, TyContext::Location(location)); + } } } @@ -929,27 +936,18 @@ macro_rules! make_mir_visitor { _ct: $(& $mutability)? ty::Const<'tcx>, _location: Location, ) { - } - fn super_span(&mut self, _span: $(& $mutability)? Span) { - } + fn super_span(&mut self, _span: $(& $mutability)? Span) {} fn super_source_info(&mut self, source_info: & $($mutability)? SourceInfo) { - let SourceInfo { - span, - scope, - } = source_info; + let SourceInfo { span, scope } = source_info; self.visit_span($(& $mutability)? *span); self.visit_source_scope($(& $mutability)? *scope); } - fn super_user_type_projection( - &mut self, - _ty: & $($mutability)? UserTypeProjection, - ) { - } + fn super_user_type_projection(&mut self, _ty: & $($mutability)? UserTypeProjection) {} fn super_user_type_annotation( &mut self, @@ -960,14 +958,11 @@ macro_rules! make_mir_visitor { self.visit_ty($(& $mutability)? ty.inferred_ty, TyContext::UserTy(ty.span)); } - fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) { - } + fn super_ty(&mut self, _ty: $(& $mutability)? Ty<'tcx>) {} - fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) { - } + fn super_region(&mut self, _region: $(& $mutability)? ty::Region<'tcx>) {} - fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) { - } + fn super_args(&mut self, _args: & $($mutability)? GenericArgsRef<'tcx>) {} // Convenience methods @@ -976,7 +971,8 @@ macro_rules! make_mir_visitor { body: &$($mutability)? Body<'tcx>, location: Location ) { - let basic_block = & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; + let basic_block = + & $($mutability)? basic_blocks!(body, $($mutability, true)?)[location.block]; if basic_block.statements.len() == location.statement_index { if let Some(ref $($mutability)? terminator) = basic_block.terminator { self.visit_terminator(terminator, location) @@ -1255,28 +1251,6 @@ macro_rules! visit_place_fns { make_mir_visitor!(Visitor,); make_mir_visitor!(MutVisitor, mut); -pub trait MirVisitable<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>); -} - -impl<'tcx> MirVisitable<'tcx> for Statement<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_statement(self, location) - } -} - -impl<'tcx> MirVisitable<'tcx> for Terminator<'tcx> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_terminator(self, location) - } -} - -impl<'tcx> MirVisitable<'tcx> for Option> { - fn apply(&self, location: Location, visitor: &mut dyn Visitor<'tcx>) { - visitor.visit_terminator(self.as_ref().unwrap(), location) - } -} - /// Extra information passed to `visit_ty` and friends to give context /// about where the type etc appears. #[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]